zoukankan      html  css  js  c++  java
  • [转]windows BLE编程 net winform 连接蓝牙4.0

    本文转自:https://www.cnblogs.com/webtojs/p/9675956.html

    winform 程序调用Windows.Devices.Bluetoot API 实现windows下BLE蓝牙设备自动连接,收发数据功能。不需要使用win10的UWP开发。

    先贴图,回头来完善代码

    源码如下:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Windows.Devices.Bluetooth;
    using Windows.Devices.Bluetooth.GenericAttributeProfile;
    using Windows.Devices.Enumeration;
    using Windows.Foundation;
    using Windows.Security.Cryptography;
    
    namespace BLECode
    {
        public class BluetoothLECode
        {
            //存储检测的设备MAC。
            public string CurrentDeviceMAC { get; set; }
            //存储检测到的设备。
            public BluetoothLEDevice CurrentDevice { get; set; }
            //存储检测到的主服务。
            public GattDeviceService CurrentService { get; set; }
            //存储检测到的写特征对象。
            public GattCharacteristic CurrentWriteCharacteristic { get; set; }
            //存储检测到的通知特征对象。
            public GattCharacteristic CurrentNotifyCharacteristic { get; set; }
    
            public string ServiceGuid { get; set; }
    
            public string WriteCharacteristicGuid { get; set; }
            public string NotifyCharacteristicGuid { get; set; }
    
    
            private const int CHARACTERISTIC_INDEX = 0;
            //特性通知类型通知启用
            private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;
    
    
            private Boolean asyncLock = false;
    
            private DeviceWatcher deviceWatcher;
    
           
    
            //定义一个委托
            public delegate void eventRun(MsgType type, string str,byte[] data=null);
            //定义一个事件
            public event eventRun ValueChanged;
    
    
    
            public BluetoothLECode(string serviceGuid, string writeCharacteristicGuid, string notifyCharacteristicGuid)
            {
                ServiceGuid = serviceGuid;
                WriteCharacteristicGuid = writeCharacteristicGuid;
                NotifyCharacteristicGuid = notifyCharacteristicGuid;
            }
    
            public void StartBleDeviceWatcher()
            {
    
                string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
                string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:="{bb7bb05e-5972-42b5-94fc-76eaa7084d49}")";
    
                deviceWatcher =
                        DeviceInformation.CreateWatcher(
                            aqsAllBluetoothLEDevices,
                            requestedProperties,
                            DeviceInformationKind.AssociationEndpoint);
    
                // Register event handlers before starting the watcher.
                deviceWatcher.Added += DeviceWatcher_Added;
                deviceWatcher.Stopped += DeviceWatcher_Stopped;
                deviceWatcher.Start();
                string msg = "自动发现设备中..";
    
                ValueChanged(MsgType.NotifyTxt, msg);
            }
    
    
            private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
            {
                string msg = "自动发现设备停止";
                ValueChanged(MsgType.NotifyTxt, msg);
            }
    
            private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
            {
                ValueChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);
                if (args.Id.EndsWith(CurrentDeviceMAC))
                {
                    Matching(args.Id);
                }
    
    
            }
    
            /// <summary>
            /// 按MAC地址查找系统中配对设备
            /// </summary>
            /// <param name="MAC"></param>
            public async Task SelectDevice(string MAC)
            {
                CurrentDeviceMAC = MAC;
                CurrentDevice = null;
                DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        DeviceInformationCollection deviceInformation = asyncInfo.GetResults();
                        foreach (DeviceInformation di in deviceInformation)
                        {
                            await Matching(di.Id);
                        }
                        if (CurrentDevice == null)
                        {
                            string msg = "没有发现设备";
                            ValueChanged(MsgType.NotifyTxt, msg);
                            StartBleDeviceWatcher();
                        }
                    }
                };
            }
            /// <summary>
            /// 按MAC地址直接组装设备ID查找设备
            /// </summary>
            /// <param name="MAC"></param>
            /// <returns></returns>
            public async Task SelectDeviceFromIdAsync(string MAC)
            {
                CurrentDeviceMAC = MAC;
                CurrentDevice = null;
                BluetoothAdapter.GetDefaultAsync().Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        BluetoothAdapter mBluetoothAdapter = asyncInfo.GetResults();
                        byte[] _Bytes1 = BitConverter.GetBytes(mBluetoothAdapter.BluetoothAddress);//ulong转换为byte数组
                        Array.Reverse(_Bytes1);
                        string macAddress = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();
                        string Id = "BluetoothLE#BluetoothLE" + macAddress + "-" + MAC;
                        await Matching(Id);
                    }
    
                };
    
            }
    
            private async Task Matching(string Id)
            {
    
                try
                {
                    BluetoothLEDevice.FromIdAsync(Id).Completed = async (asyncInfo, asyncStatus) =>
                    {
                        if (asyncStatus == AsyncStatus.Completed)
                        {
                            BluetoothLEDevice bleDevice = asyncInfo.GetResults();
                            //在当前设备变量中保存检测到的设备。
                            CurrentDevice = bleDevice;
                            await Connect();
    
                        }
                    };
                }
                catch (Exception e)
                {
                    string msg = "没有发现设备" + e.ToString();
                    ValueChanged(MsgType.NotifyTxt, msg);
                    StartBleDeviceWatcher();
                }
    
            }
    
            private async Task Connect()
            {
                string msg = "正在连接设备<" + CurrentDeviceMAC + ">..";
                ValueChanged(MsgType.NotifyTxt, msg);
                CurrentDevice.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;
                await SelectDeviceService();
    
            }
    
    
            /// <summary>
            /// 主动断开连接
            /// </summary>
            /// <returns></returns>
            public void Dispose()
            {
    
                CurrentDeviceMAC = null;
                CurrentService?.Dispose();
                CurrentDevice?.Dispose();
                CurrentDevice = null;
                CurrentService = null;
                CurrentWriteCharacteristic = null;
                CurrentNotifyCharacteristic = null;
                ValueChanged(MsgType.NotifyTxt, "主动断开连接");
    
            }
    
            private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
            {
                if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
                {
                    string msg = "设备已断开,自动重连";
                    ValueChanged(MsgType.NotifyTxt, msg);
                    if (!asyncLock)
                    {
                        asyncLock = true;
                        CurrentDevice.Dispose();
                        CurrentDevice = null;
                        CurrentService = null;
                        CurrentWriteCharacteristic = null;
                        CurrentNotifyCharacteristic = null;
                        SelectDeviceFromIdAsync(CurrentDeviceMAC);
                    }
    
                }
                else
                {
                    string msg = "设备已连接";
                    ValueChanged(MsgType.NotifyTxt, msg);
                }
            }
            /// <summary>
            /// 按GUID 查找主服务
            /// </summary>
            /// <param name="characteristic">GUID 字符串</param>
            /// <returns></returns>
            public async Task SelectDeviceService()
            {
                Guid guid = new Guid(ServiceGuid);
                CurrentDevice.GetGattServicesForUuidAsync(guid).Completed = (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        try
                        {
                            GattDeviceServicesResult result = asyncInfo.GetResults();
                            string msg = "主服务=" + CurrentDevice.ConnectionStatus;
                            ValueChanged(MsgType.NotifyTxt, msg);
                            if (result.Services.Count > 0)
                            {
                                CurrentService = result.Services[CHARACTERISTIC_INDEX];
                                if (CurrentService != null)
                                {
                                    asyncLock = true;
                                    GetCurrentWriteCharacteristic();
                                    GetCurrentNotifyCharacteristic();
    
                                }
                            }
                            else
                            {
                                msg = "没有发现服务,自动重试中";
                                ValueChanged(MsgType.NotifyTxt, msg);
                                SelectDeviceService();
                            }
                        }
                        catch (Exception e)
                        {
                            ValueChanged(MsgType.NotifyTxt, "没有发现服务,自动重试中");
                            SelectDeviceService();
    
                        }
                    }
                };
            }
    
    
            /// <summary>
            /// 设置写特征对象。
            /// </summary>
            /// <returns></returns>
            public async Task GetCurrentWriteCharacteristic()
            {
    
                string msg = "";
                Guid guid = new Guid(WriteCharacteristicGuid);
                CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        GattCharacteristicsResult result = asyncInfo.GetResults();
                        msg = "特征对象=" + CurrentDevice.ConnectionStatus;
                        ValueChanged(MsgType.NotifyTxt, msg);
                        if (result.Characteristics.Count > 0)
                        {
                            CurrentWriteCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
                        }
                        else
                        {
                            msg = "没有发现特征对象,自动重试中";
                            ValueChanged(MsgType.NotifyTxt, msg);
                            await GetCurrentWriteCharacteristic();
                        }
                    }
                };
            }
    
    
    
    
            /// <summary>
            /// 发送数据接口
            /// </summary>
            /// <param name="characteristic"></param>
            /// <param name="data"></param>
            /// <returns></returns>
            public async Task Write(byte[] data)
            {
                if (CurrentWriteCharacteristic != null)
                {
                    CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);
                }
    
            }
    
            /// <summary>
            /// 设置通知特征对象。
            /// </summary>
            /// <returns></returns>
            public async Task GetCurrentNotifyCharacteristic()
            {
                string msg = "";
                Guid guid = new Guid(NotifyCharacteristicGuid);
                CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        GattCharacteristicsResult result = asyncInfo.GetResults();
                        msg = "特征对象=" + CurrentDevice.ConnectionStatus;
                        ValueChanged(MsgType.NotifyTxt, msg);
                        if (result.Characteristics.Count > 0)
                        {
                            CurrentNotifyCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
                            CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
                            CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
                            await EnableNotifications(CurrentNotifyCharacteristic);
    
                        }
                        else
                        {
                            msg = "没有发现特征对象,自动重试中";
                            ValueChanged(MsgType.NotifyTxt, msg);
                            await GetCurrentNotifyCharacteristic();
                        }
                    }
                };
            }
    
            /// <summary>
            /// 设置特征对象为接收通知对象
            /// </summary>
            /// <param name="characteristic"></param>
            /// <returns></returns>
            public async Task EnableNotifications(GattCharacteristic characteristic)
            {
                string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;
                ValueChanged(MsgType.NotifyTxt, msg);
    
                characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = async (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        GattCommunicationStatus status = asyncInfo.GetResults();
                        if (status == GattCommunicationStatus.Unreachable)
                        {
                            msg = "设备不可用";
                            ValueChanged(MsgType.NotifyTxt, msg);
                            if (CurrentNotifyCharacteristic != null && !asyncLock)
                            {
                                await EnableNotifications(CurrentNotifyCharacteristic);
                            }
                        }
                        asyncLock = false;
                        msg = "设备连接状态" + status;
                        ValueChanged(MsgType.NotifyTxt, msg);
                    }
                };
            }
    
            private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
            {
                byte[] data;
                CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
                string str = BitConverter.ToString(data);
                ValueChanged(MsgType.BLEData,str, data);
    
            }
        }
    
        public enum MsgType
        {
            NotifyTxt,
            BLEData
        }
    }
    复制代码

    调用方式:

               bluetooth = new BluetoothLECode(_serviceGuid, _writeCharacteristicGuid, _notifyCharacteristicGuid);
                bluetooth.ValueChanged += Bluetooth_ValueChanged; 

     如果你无法编译上面的类库,请直接使用我生成的DLL文件

      https://files.cnblogs.com/files/webtojs/BLECode.rar

  • 相关阅读:
    DDD 领域驱动设计
    IOC 控制反转
    WCF
    Lucene 全文检索引擎
    Redis
    Cache 缓存
    return
    PHP中empty();和isset();的区别.
    sql 简单用语
    关系型数据库
  • 原文地址:https://www.cnblogs.com/freeliver54/p/9993648.html
Copyright © 2011-2022 走看看