对于一个项目,我需要从使用C#的Windows 10上的蓝牙设备获取一些数据。 我不太熟悉的蓝牙API,不知道为什么以下不起作用:
使用BluetoothLEAdvertisementWatcher
我search广告,这工作正常。 我确实收到来自设备的广告(本地名称适合)以及它的ServiceUuids
。 接下来我尝试使用与广告一起收到的BluetoothAddress
连接到设备:
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs) { ulong blAdress = eventArgs.BluetoothAddress; BluetoothLEDevice blDevice = await Windows.Devices.Bluetooth.BluetoothLEDevice.FromBluetoothAddressAsync(blAdress); }
但是,这样做会导致一个例外:
元素未find。 (从HRESULTexception:0x80070490)。
这是从设备读取数据的正确方法吗? 其他选项是否可用于从服务中读取数据? 在Windows中手动配对设备不是一个真正的select,也似乎失败。
/编辑1:我检查设备的本地名称,以确保我只尝试连接到正确的。 所以我想连接到这个特定的设备有一个问题,但我不知道如何解决这个问题。 服务数据在iOS上成功读取,所以应该是可以的。
直到MS修复这个问题,我发现连接到BLE设备的唯一可靠的解决方案是要求注册表列出配对的BLE设备,并将广告中的蓝牙地址与配对设备的注册表列表进行比较。 我的经验是,当在不成对的设备上调用FromBluetoothAddressAsync时,Windows将引发异常并杀死观察者线程。 我有一些C ++代码,我很乐意分享,读取注册表并创建配对的BLE设备列表。
希望MS会花时间以苹果公司的方式全力支持BLE。
这里是MS的参考( https://social.msdn.microsoft.com/Forums/vstudio/en-US/e321cb3c-462a-4b16-b7e4-febdb3d0c7d6/windows-10-pairing-a-ble-device-from -code?forum = wdk )。 看来,要使用此BluetoothLEDevice.FromBluetoothAddressAsync,我们必须处理该设备是广告,但尚未配对的异常。
我直接使用BluetoothLEAdvertisementWatcher时遇到了同样的问题。
然后我测试了观察者列出的不同地址。 我发现它与蓝牙设备有关。
如下添加过滤器后,我可以成功连接到GATT设备(TI传感器标签)。
public sealed partial class MainPage : Page { private BluetoothLEAdvertisementWatcher watcher; public MainPage() { this.InitializeComponent(); // Create and initialize a new watcher instance. watcher = new BluetoothLEAdvertisementWatcher(); // Part 1B: Configuring the signal strength filter for proximity scenarios // Configure the signal strength filter to only propagate events when in-range // Please adjust these values if you cannot receive any advertisement // Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm // will start to be considered "in-range". watcher.SignalStrengthFilter.InRangeThresholdInDBm = -70; // Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction with OutOfRangeTimeout // to determine when an advertisement is no longer considered "in-range" watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75; // Set the out-of-range timeout to be 2 seconds. Used in conjunction with OutOfRangeThresholdInDBm // to determine when an advertisement is no longer considered "in-range" watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000); // By default, the sampling interval is set to zero, which means there is no sampling and all // the advertisement received is returned in the Received event // End of watcher configuration. There is no need to comment out any code beyond this point. } protected override void OnNavigatedTo(NavigationEventArgs e) { watcher.Received += OnAdvertisementReceived; watcher.Stopped += OnAdvertisementWatcherStopped; App.Current.Suspending += App_Suspending; App.Current.Resuming += App_Resuming; } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { App.Current.Suspending -= App_Suspending; App.Current.Resuming -= App_Resuming; watcher.Stop(); watcher.Received -= OnAdvertisementReceived; watcher.Stopped -= OnAdvertisementWatcherStopped; base.OnNavigatingFrom(e); } private void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e) { // Make sure to stop the watcher on suspend. watcher.Stop(); // Always unregister the handlers to release the resources to prevent leaks. watcher.Received -= OnAdvertisementReceived; watcher.Stopped -= OnAdvertisementWatcherStopped; } private void App_Resuming(object sender, object e) { watcher.Received += OnAdvertisementReceived; watcher.Stopped += OnAdvertisementWatcherStopped; } private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs) { var address = eventArgs.BluetoothAddress; BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(address); var cnt =device.GattServices.Count; watcher.Stop(); } /// <summary> /// Invoked as an event handler when the watcher is stopped or aborted. /// </summary> /// <param name="watcher">Instance of watcher that triggered the event.</param> /// <param name="eventArgs">Event data containing information about why the watcher stopped or aborted.</param> private void OnAdvertisementWatcherStopped(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementWatcherStoppedEventArgs eventArgs) { } private void start_Click(object sender, RoutedEventArgs e) { watcher.Start(); } }
只是一个猜测,但也许你需要这个:
watcher.ScanningMode = BluetoothLEScanningMode.Active;
并在OnAdvertisementReceived事件
if (e.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse) { BluetoothLEDevice blDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(e.BluetoothAddress); }