我有一个 BLE 应用程序。 当我开始设备扫描时,
DeviceWatcher.Added
事件将立即调用并显示之前连接的设备当前已关闭。但在DeviceWatcher.Removed
事件中它将被清除。
我怎样才能避免这种情况呢?在我的应用程序中,当
DeviceWatcher.Added
事件中列出设备时,我尝试立即连接设备。我不想等到DeviceWatcher.EnumerationCompleted
活动。
由于此实现,连接 API
BluetoothLEDevice bluetoothLEDevice = BluetoothLEDevice::FromIdAsync(GetId()).get();
返回成功。在服务扫描 API GattDeviceServicesResult result = m_BluetoothLEDevice.GetGattServicesAsync(BluetoothCacheMode::Uncached).get();
中,我获得 GattCommunicationStatus::Unreachable
状态。
我在第一次扫描时需要这个状态。或者还有其他方法可以检查设备是否无法访问?
这里编写的示例是用 C# 编写的,您可以在 learn.microsoft.com
中找到 C++ 替代品var pairedBleDevices = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)); # Return all the paired Bluetooth LE devices
现在,如果您想删除特定设备的配对,您可以循环遍历pairedBleDevices,并通过匹配特定属性(例如设备名称或地址)找到您的删除设备。
foreach (var device in pairedBleDevices )
{
if (!device::Name.Contains("myDevice")) continue;
await device.Pairing.UnpairAsync();
break;
}
现在,正如 Mike 建议的那样,您拥有所有先前配对的 LE 设备的属性,您可以使用 BluetoothLEAdvertisementWatcher 来发现 BLE 设备并通过匹配蓝牙地址(来自配对设备)来过滤广告。如果发现新设备,请配对设备或执行 GATT 操作并开始通信。
您收到 GattCommunicationStatus::Unreachable 这可能是您尝试通信的设备处于睡眠模式。所以最好的方法是先使用BluetoothLEAdvertisementWatcher捕获广告,然后启动配对或GATT操作。
我觉得答案就在你的问题中。与其他答案一样,这是用 C# 编写的,但很容易转换;
private async void HandleFoundDevice(DeviceWatcher sender, DeviceInformation e)
{
var id = e.Id;
var bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(id);
GattDeviceServicesResult gatServiceAsync = await bluetoothLEDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached);
if (gatServiceAsync.Status == GattCommunicationStatus.Success)
{
// add your device to your list / invoke a call back to your caller somewhere / etc.
}
}
只需将此句柄添加到设备观察器即可;
mDeviceWatcher.Added += HandleFoundDevice;
当您创建观察者时,可以在过滤器中执行此操作,但我无法让它工作。可能和蓝牙缓存有关系。从 Windows 端来看,感觉有问题。但上面的代码阻止了 OP 描述的行为。