美文网首页
winform、wpf蓝牙扫描的三种方式

winform、wpf蓝牙扫描的三种方式

作者: Camellia666 | 来源:发表于2020-08-27 18:19 被阅读0次

1,先说结论

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

接下来是一波废话:

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

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

2,Inthehand同步搜索

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

1,添加依赖

32feet.PNG

2,撸码

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,效果

1.gif

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

3,Inthehand异步搜索

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

1,撸码

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));
    }
}

2,效果

2.gif

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

4,基于winSDK的ble扫描

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

1,准备

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

2,添加win10 SDK依赖

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

win10refer.PNG

如果你的项目中默认没有添加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

3,撸码

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();
    }
}

4,效果

3.gif

相关文章

  • winform、wpf蓝牙扫描的三种方式

    1,先说结论 本文介绍如何在winform、wpf中实现经典蓝牙扫描(同步方式和异步方式),以及实现基于win10...

  • Dpi Aware

    设置 获取虚拟屏幕的尺寸的三种方式 通过api获取 通过winform获取 通过wpf获取 坑 dpi不为100%...

  • WPF与WinForm开发有什么区别?

    WPF开发于WinForm之后,从技术发展的角度,WPF比WinForm先进是不容置疑的。我觉得WPF相比于Win...

  • WPF简介

    目录 什么是WPF? WPF的历史? 为什么要用WPF及WPF作用 WPF与winForm区别? 什么是WPF? ...

  • 技术总结:winform和wpf的区别 以及 项目的“设计规划”

    一、winform和wpf的区别: 1.winform 是“前后端”不分离的,wpf是前后端分离的。这个是winf...

  • WPF初印象

    一、与WPF结缘 第一次接触WPF是在2012年。学习了WinForm编程之后,了解到WPF这个非常先进的UI框架...

  • Android蓝牙扫描

    蓝牙扫描的目的在于发现设备或者接收设备广播,设备包括经典蓝牙设备和BLE蓝牙设备,这两种设备的扫描方式不同。 经典...

  • WPF承载winform控件

    主要是最近的WPF项目中,用到了别的公司的东西,需要调用dll来使用该公司的控件。 在WPF中使用WinForm主...

  • 控件开发选型指南

    本文概要   如果你是从WinForm框架转到WPF框架的开发人员,我想你肯定是已经超级厌烦了WinForm自定义...

  • vs NetCore3.0创建WPF/WinForm程序记录

    在创建WPF/WinForm程序后,需要修改程序集内容为如下: WinExe

网友评论

      本文标题:winform、wpf蓝牙扫描的三种方式

      本文链接:https://www.haomeiwen.com/subject/rukhsktx.html