我正在BluetoothLEAdvertisementWatcher
寻找附近的BLE设备,并且运行良好。找到它们之后,我想通过GATT连接和读取/写入数据。但是在获取BluetoothLEAdvertisement
(https://msdn.microsoft.com/de-de/library/windows/apps/windows.devices.bluetooth.genericattributeprofile)之后,我不知道如何使用API 。
public class Adapter
{
private readonly BluetoothLEAdvertisementWatcher _bleWatcher = new BluetoothLEAdvertisementWatcher();
public Adapter()
{
_bleWatcher.Received += BleWatcherOnReceived;
}
private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
// how to connect?
// I know, it's the wrong place to to this, but this is just an example
}
public void StartScanningForDevices(Guid[] serviceUuids)
{
_blewatcher.advertisementfilter.advertisement.serviceuuids.clear();
foreach (var uuid in serviceuuids)
{
_blewatcher.advertisementfilter.advertisement.serviceuuids.add(uuid);
}
_blewatcher.start();
}
}
我发现正在使用DeviceInformation.FindAllAsync
而不是的样本,BluetoothLEAdvertisementWatcher
但这些样本无法正常工作/找不到任何设备。
更新
经过一段时间的挖掘,我发现了以下方法。但不幸的是,配对失败。该设备只是带有BLE屏蔽的Arduino。我绝对可以连接Android和iOS。因此,以某种方式使用UWP必须有可能。:/
private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
// dev.DeviceInformation.Pairing.CanPair is true
// dpr.Status is Failed
DevicePairingResult dpr = await dev.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
var service = await GattDeviceService.FromIdAsync(dev.DeviceInformation.Id);
}
更新#2
我现在可以发现并配对(不稳定,但暂时还可以),但是
var service = await GattDeviceService.FromIdAsync(args.Id);
引发以下异常
System.IO.FileNotFoundException:系统找不到指定的文件。(来自HRESULT的异常:0x80070002)
我不知道为什么。
更新04/17-创建者更新
Microsoft刚刚更新了其蓝牙API。现在,我们有未配对的BLE设备通信!
目前,他们的文档很少,但这是简化得多的新结构:
BleWatcher = new BluetoothLEAdvertisementWatcher
{
ScanningMode = BluetoothLEScanningMode.Active
};
BleWatcher.Start();
BleWatcher.Received += async (w, btAdv) => {
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress);
Debug.WriteLine($"BLEWATCHER Found: {device.name}");
// SERVICES!!
var gatt = await device.GetGattServicesAsync();
Debug.WriteLine($"{device.Name} Services: {gatt.Services.Count}, {gatt.Status}, {gatt.ProtocolError}");
// CHARACTERISTICS!!
var characs = await gatt.Services.Single(s => s.Uuid == SAMPLESERVICEUUID).GetCharacteristicsAsync();
var charac = characs.Single(c => c.Uuid == SAMPLECHARACUUID);
await charac.WriteValueAsync(SOMEDATA);
};
现在好多了。正如我所说的,目前几乎没有文档,我有一个奇怪的问题,即ValueChanged回调在30秒左右后停止调用,尽管这似乎是一个单独的范围界定问题。
更新2-有些古怪
在与新的创建者进行更多的更新之后,构建BLE应用程序时还需要考虑一些其他事项。
ValueChanged
则charac
可能会遇到此问题。这是因为GattCharacteristic
应先将其处置,然后将特征设置为全局特征,而不要依赖于其被复制到其中。App.xml.cs
OnSuspended
回调来终止连接。否则,您会陷入一种奇怪的状态,即Windows似乎维护(并继续阅读!)BLE连接。好吧,它有它的怪癖,但它有效!
老答案
遵循杰森(Jason)关于需要配对以使其服务被发现的设备的正确答案,下面是一些示例代码来解决此问题:
private void SetupBluetooth()
{
Watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
Watcher.Received += DeviceFound;
DeviceWatcher = DeviceInformation.CreateWatcher();
DeviceWatcher.Added += DeviceAdded;
DeviceWatcher.Updated += DeviceUpdated;
StartScanning();
}
private void StartScanning()
{
Watcher.Start();
DeviceWatcher.Start();
}
private void StopScanning()
{
Watcher.Stop();
DeviceWatcher.Stop();
}
private async void DeviceFound(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs btAdv)
{
if (_devices.Contains(btAdv.Advertisement.LocalName))
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
{
Debug.WriteLine($"---------------------- {btAdv.Advertisement.LocalName} ----------------------");
Debug.WriteLine($"Advertisement Data: {btAdv.Advertisement.ServiceUuids.Count}");
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress);
var result = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
Debug.WriteLine($"Pairing Result: {result.Status}");
Debug.WriteLine($"Connected Data: {device.GattServices.Count}");
});
}
}
private async void DeviceAdded(DeviceWatcher watcher, DeviceInformation device)
{
if (_devices.Contains(device.Name))
{
try
{
var service = await GattDeviceService.FromIdAsync(device.Id);
Debug.WriteLine("Opened Service!!");
}
catch
{
Debug.WriteLine("Failed to open service.");
}
}
}
private void DeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate update)
{
Debug.WriteLine($"Device updated: {update.Id}");
}
这里要注意的关键事项是:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句