如何在 windows 桌面应用程序的 phone 上配对和搜索低功耗蓝牙服务?
How to pair and search Bluetooth Low Energy services on phone in windows desktop application?
我们得到了 phone 应用程序,该应用程序托管具有服务和特性的 GATT 服务器。在桌面应用程序中,我们尝试使用 DeviceWatcher API 通过 UWP 搜索它。
var deviceWatcher = DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
new List<string>(),
DeviceInformationKind.AssociationEndpoint);
然后我们尝试从设备获取服务
var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);
但是这种方式很不稳定。查找并连接到设备需要 30-60 秒。有时找不到设备或找到设备但无法获得服务。
我们还尝试将设备与 PC 配对,并仅检查配对或连接的设备
var deviceWatcher = DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(true),
new List<string>(),
DeviceInformationKind.AssociationEndpoint);
但是这个观察者没有发现任何东西。我们尝试了不同的 AQS 过滤器并得到了相同的结果。
我们还尝试使用 32feet 库来仅获取配对的连接设备。
var client = new BluetoothClient();
var paired = client.DiscoverDevices(5, true, true, false);
foreach (var bluetoothDeviceInfo in paired)
{
var addressBytes = bluetoothDeviceInfo.DeviceAddress.ToByteArray();
var addr = BitConverter.ToUInt64(addressBytes, 0);
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(addr));
var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);
}
它运行速度很快并找到了 phone,但是找到的设备不包含我们的 GATT 服务,并且它的蓝牙地址与 DeviceWatcher 找到的设备不同。看起来一个设备上有两个蓝牙设备 phone:第一个设备有我们的 BLE 服务,第二个已配对但没有服务。
有什么方法可以配对正确的 BLE 设备并只搜索已配对的设备吗?
我终于找到了如何使用 BluetoothLEAdvertisementWatcher 直接搜索服务。
_watcher = new BluetoothLEAdvertisementWatcher();
_watcher.ScanningMode = BluetoothLEScanningMode.Active;
_watcher.SignalStrengthFilter = new BluetoothSignalStrengthFilter
{
InRangeThresholdInDBm = -75,
OutOfRangeThresholdInDBm = -76,
OutOfRangeTimeout = TimeSpan.FromSeconds(2),
SamplingInterval = TimeSpan.FromSeconds(2)
};
_watcher.AdvertisementFilter =
new BluetoothLEAdvertisementFilter
{
Advertisement =
new BluetoothLEAdvertisement
{
ServiceUuids =
{
BLEHelper.ServiceId
}
}
};
_watcher.Received += OnWatcherOnReceived;
_watcher.Start();
在 OnWatcherOnReceived 中我们可以获取蓝牙地址以连接到服务并获取特征
private void OnWatcherOnReceived(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs a)
{
// use a.BluetoothAddress to connect to device
}
我们得到了 phone 应用程序,该应用程序托管具有服务和特性的 GATT 服务器。在桌面应用程序中,我们尝试使用 DeviceWatcher API 通过 UWP 搜索它。
var deviceWatcher = DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
new List<string>(),
DeviceInformationKind.AssociationEndpoint);
然后我们尝试从设备获取服务
var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);
但是这种方式很不稳定。查找并连接到设备需要 30-60 秒。有时找不到设备或找到设备但无法获得服务。
我们还尝试将设备与 PC 配对,并仅检查配对或连接的设备
var deviceWatcher = DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(true),
new List<string>(),
DeviceInformationKind.AssociationEndpoint);
但是这个观察者没有发现任何东西。我们尝试了不同的 AQS 过滤器并得到了相同的结果。
我们还尝试使用 32feet 库来仅获取配对的连接设备。
var client = new BluetoothClient();
var paired = client.DiscoverDevices(5, true, true, false);
foreach (var bluetoothDeviceInfo in paired)
{
var addressBytes = bluetoothDeviceInfo.DeviceAddress.ToByteArray();
var addr = BitConverter.ToUInt64(addressBytes, 0);
var device = await BluetoothLEDevice.FromBluetoothAddressAsync(addr));
var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);
}
它运行速度很快并找到了 phone,但是找到的设备不包含我们的 GATT 服务,并且它的蓝牙地址与 DeviceWatcher 找到的设备不同。看起来一个设备上有两个蓝牙设备 phone:第一个设备有我们的 BLE 服务,第二个已配对但没有服务。
有什么方法可以配对正确的 BLE 设备并只搜索已配对的设备吗?
我终于找到了如何使用 BluetoothLEAdvertisementWatcher 直接搜索服务。
_watcher = new BluetoothLEAdvertisementWatcher();
_watcher.ScanningMode = BluetoothLEScanningMode.Active;
_watcher.SignalStrengthFilter = new BluetoothSignalStrengthFilter
{
InRangeThresholdInDBm = -75,
OutOfRangeThresholdInDBm = -76,
OutOfRangeTimeout = TimeSpan.FromSeconds(2),
SamplingInterval = TimeSpan.FromSeconds(2)
};
_watcher.AdvertisementFilter =
new BluetoothLEAdvertisementFilter
{
Advertisement =
new BluetoothLEAdvertisement
{
ServiceUuids =
{
BLEHelper.ServiceId
}
}
};
_watcher.Received += OnWatcherOnReceived;
_watcher.Start();
在 OnWatcherOnReceived 中我们可以获取蓝牙地址以连接到服务并获取特征
private void OnWatcherOnReceived(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs a)
{
// use a.BluetoothAddress to connect to device
}