基于winSDK的ble扫描
ble扫描可以扫描到ble设备,可以添加过滤条件,只搜索特定的设备,并且可以获取其信号强度。微软官方demo是基于uwp的,迁移到 wpf下,还是有点麻烦的。主要过程如下:
1,准备
需要你在win10环境下,并且vs安装了win10 SDK。
2,添加win10 SDK依赖
如果你的项目中默认没有添加WindowsBase的话也要手动引入。
这三个依赖的参考位置如下: 1) C:\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd 2) C:\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd
3) C:\Program Files\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2\WindowsBase.dll
- 代码实现
public partial class BleScan : Window { private BluetoothLEAdvertisementWatcher watcher;
private BluetoothLEManufacturerData manufacturerData;
public BleScan()
{
InitializeComponent();
initBluetooth();
}
private void initBluetooth()
{
watcher = new BluetoothLEAdvertisementWatcher();
var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 0x014C;
var writer = new DataWriter();
writer.WriteUInt16(0x0719);
manufacturerData.Data = writer.DetachBuffer();
// 过滤条件:companyId = 0x014C 且值为:0x0719的广播。可自行修改或删除
watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);
// 根据信号强度过滤
watcher.SignalStrengthFilter.InRangeThresholdInDBm = -50;
watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -55;
watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);
watcher.Received += OnAdvertisementReceived;
watcher.Stopped += OnAdvertisementWatcherStopped;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
watcher.Start();
}
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
// 信号强度
Int16 rssi = eventArgs.RawSignalStrengthInDBm;
// 蓝牙地址
string addr = CommonUtil.btAddrFormat2(eventArgs.BluetoothAddress.ToString("x8"));
string manufacturerDataString = "";
var manufacturerSections = eventArgs.Advertisement.ManufacturerData;
if (manufacturerSections.Count > 0)
{
// Only print the first one of the list
var manufacturerData = manufacturerSections[0];
var data = new byte[manufacturerData.Data.Length];
using (var reader = DataReader.FromBuffer(manufacturerData.Data))
{
reader.ReadBytes(data);
}
manufacturerDataString = BitConverter.ToString(data);
}
// Serialize UI update to the main UI thread
this.btnScan.Dispatcher.Invoke(() =>
{
listBox.Items.Add(String.Format("address:{0}, rssi:{1}, manufacturer:{2}", addr, rssi, manufacturerDataString));
});
}
private async void OnAdvertisementWatcherStopped(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementWatcherStoppedEventArgs eventArgs)
{
this.btnScan.Dispatcher.Invoke(() =>
{
});
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
watcher.Received -= OnAdvertisementReceived;
watcher.Stopped -= OnAdvertisementWatcherStopped;
watcher.Stop();
}
}