相关文章推荐
完美的硬盘  ·  “sp_rename ...·  7 月前    · 
犯傻的菠萝  ·  ICASSP ...·  11 月前    · 
不拘小节的双杠  ·  FFmpeg tips for FLAC ...·  1 年前    · 

本文介绍如何在winform、wpf中实现经典蓝牙扫描(同步方式和异步方式),以及实现基于win10的ble扫描。

接下来是一波废话:

由于公司业务需求,需要在windows桌面软件中实现蓝牙设备搜索功能。

一番摆渡后发现基本上用的都是 Inthehand 的,这个库只能搜索到bt3经典蓝牙,可以实现同步搜索和异步搜索。要想实现ble搜索需要基于win10 SDK进行开发,微软官方 demo 是基于uwp的,那么可以实现在winform/wpf中使用吗?经过一番操作,实现了在wpf中调动win10 SDK进行ble搜索,但是必须要在win10环境下运行。

2,Inthehand同步搜索

所谓同步搜索就是固定扫描一段时间(大概10s钟的样子),然后返回扫描到的所有蓝牙设备。

1,添加依赖

首先通过nuget添加 32feet.NET 依赖
在这里插入图片描述

public partial class Bt3SyncScan : Window
	private BluetoothClient blueClient;
	public Bt3SyncScan()
		InitializeComponent();
		BluetoothRadio BuleRadio = BluetoothRadio.PrimaryRadio;
		BuleRadio.Mode = RadioMode.Discoverable;
		blueClient = new BluetoothClient();
	private void Button_Click(object sender, RoutedEventArgs e)
		// 异步扫描
		new Thread(() =>
			IReadOnlyCollection<BluetoothDeviceInfo> Devices = blueClient.DiscoverDevices();
			foreach (BluetoothDeviceInfo device in Devices)
				//地址做一下美化
				String addr = CommonUtil.btAddrFormat(device.DeviceAddress.ToString());
				this.btnSearch.Dispatcher.Invoke(() =>
					listBox.Items.Add(addr);
		}).Start();

缺点比较明显,需要等几秒钟才展示结果。

3,Inthehand异步搜索

异步搜索和同步搜索使用的是相同的库。

public partial class Bt3AsyncScan : Window
	private BluetoothClient bluetoothClient;
	public Bt3AsyncScan()
		InitializeComponent();
		bluetoothClient = new BluetoothClient();
		BluetoothRadio bluetoothRadio = BluetoothRadio.PrimaryRadio;
		bluetoothRadio.Mode = RadioMode.Connectable;
	private void Button_Click(object sender, RoutedEventArgs e)
		BluetoothComponent bluetoothComponent = new BluetoothComponent(bluetoothClient);
		// 开始异步扫描
		bluetoothComponent.DiscoverDevicesAsync(10, false, false, false, true, bluetoothComponent);
		// 扫描结果回调
		bluetoothComponent.DiscoverDevicesProgress += BluetoothComponent_DiscoverDevicesProgress;
	private void BluetoothComponent_DiscoverDevicesProgress(object sender, DiscoverDevicesEventArgs e)
		string addr = e.Devices[0].DeviceAddress.ToString();
		listBox.Items.Add(CommonUtil.btAddrFormat(addr));

可以看出每扫描到一个设备就展示出来,速度非常快。

4,基于winSDK的ble扫描

ble扫描可以扫描到ble设备,可以添加过滤条件,只搜索特定的设备,并且可以获取其信号强度。微软官方demo是基于uwp的,迁移到 wpf下,还是有点麻烦的。主要过程如下:

需要你在win10环境下,并且vs安装了win10 SDK。

2,添加win10 SDK依赖

在你的wpf项目中添加如下引用

如果你的项目中默认没有添加WindowsBase的话也要手动引入。

这三个依赖的参考位置如下:

C:\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd
C:\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd
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();
参考: https://blog.csdn.net/code_long/article/details/105636398?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_releva..
                                    先上官方文档: 蓝牙 GATT 客户端,文档是关于UWP开发BLE的,WPF如果要使用BLE的API,得手动添加几个引用(可参考这篇文章),该文章说需要添加3个引用,但本人创建的WPF应用默认已经有 WindowBase 引用,另外只添加了一个 Windows 引用就可以使用BLE相关的API了,IDE和SDK版本如下:官方文档给出了两种方式扫描蓝牙设备,DeviceWatcher 和 BluetoothLEAdvertisementWatcher,实测后个人推荐使用 BluetoothLEAdvertis
1.1、蓝牙模块简介
XLBT232-D0101蓝牙模块采用CSR BlueCore 芯片,配置6-8Mbit 的软件存储空间,支持AT 指令,用户可根据需要更改SPP 角色(主、从模式)以及串口波特率、设备名称、配...
                                    假设我们现有一个WPF程序,需要支持1903以前的Windows 10版本。同时在1903以后的版本上,额外多出一个Ink的功能。那么我们就可以通过ApiInformation.IsApiContractPresent方法来判断1903的API是否可用,决定要不要开放Ink功能给当前用户。新来的同学如果不知道如何使用“ApiInformation.IsApiContractPresent...
                                    因项目中存在windows系统下低功耗蓝牙控制的需求,所以近期一直在进行各种尝试。 因为微软主推的uwp平台支持低功耗蓝牙控制,并且在github上开源了低功耗蓝牙的控制样例。
github上 uwp示例库地址:
https://github.com/microsoft/Windows-universal-samples
低功耗蓝牙(ble)的具体地址:
https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/Bl