c#低能耗蓝牙连接

在初学中遇到了很多问题 -好不容易调试成功-特意分享给大家
界面:
在这里插入图片描述
连接成功
在这里插入图片描述
核心代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Security.Cryptography;

namespace A_multimeter
{
    public class BleCore
    {
        private Boolean asyncLock = false;
        /// <summary>
        /// 搜索蓝牙设备对象
        /// </summary>
        //private DeviceWatcher deviceWatcher;
        /// <summary>
        /// 当前连接的服务
        /// </summary>
        public GattDeviceService CurrentService { get; set; }
        /// <summary>
        /// 当前连接的蓝牙设备
        /// </summary>
        public BluetoothLEDevice CurrentDevice { get; set; }
        /// <summary>
        /// 写特征对象
        /// </summary>
        public GattCharacteristic CurrentWriteCharacteristic { get; set; }
        /// <summary>
        /// 通知特征对象
        /// </summary>
        public GattCharacteristic CurrentNotifyCharacteristic { get; set; }
        /// <summary>
        /// 特性通知类型通知启用
        /// </summary>
        private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;
        /// <summary>
        /// 存储检测到的设备
        /// </summary>
        private List<BluetoothLEDevice> DeviceList = new List<BluetoothLEDevice>();
        /// <summary>
        /// 定义搜索蓝牙设备委托
        /// </summary>
        public delegate void DeviceWatcherChangedEvent(MsgType type, BluetoothLEDevice bluetoothLEDevice);
        /// <summary>
        /// 搜索蓝牙事件
        /// </summary>
        public event DeviceWatcherChangedEvent DeviceWatcherChanged;
        /// <summary>
        /// 获取服务委托
        /// </summary>
        public delegate void GattDeviceServiceAddedEvent(GattDeviceService gattDeviceService);
        /// <summary>
        /// 获取服务事件
        /// </summary>
        public event GattDeviceServiceAddedEvent GattDeviceServiceAdded;
        /// <summary>
        /// 获取特征委托
        /// </summary>
        public delegate void CharacteristicAddedEvent(GattCharacteristic gattCharacteristic);
        /// <summary>
        /// 获取特征事件
        /// </summary>
        public event CharacteristicAddedEvent CharacteristicAdded;
        /// <summary>
        /// 提示信息委托
        /// </summary>
        public delegate void MessAgeChangedEvent(MsgType type, string message, byte[] data = null);
        /// <summary>
        /// 提示信息事件
        /// </summary>
        public event MessAgeChangedEvent MessAgeChanged;
        /// <summary>
        /// 接受数据委托
        /// </summary>
        public delegate void RecDataEvent(MsgType type, string message, byte[] data = null);
        /// <summary>
        /// 接受数据事件
        /// </summary>
        public event RecDataEvent RcvChanged;
        /// 当前连接的蓝牙Mac
        /// </summary>
        private string CurrentDeviceMAC { get; set; }
        public BleCore()
        {
        }
        BluetoothLEAdvertisementWatcher watcher;
        /// <summary>
        /// 搜索蓝牙设备
        /// </summary>
        public void StartBleDeviceWatcher()
        {
            watcher = new BluetoothLEAdvertisementWatcher();

            watcher.ScanningMode = BluetoothLEScanningMode.Active;

            // only activate the watcher when we're recieving values >= -80
            watcher.SignalStrengthFilter.InRangeThresholdInDBm = -80;

            // stop watching if the value drops below -90 (user walked away)
            watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -90;

            // register callback for when we see an advertisements
            watcher.Received += OnAdvertisementReceived;

            // wait 5 seconds to make sure the device is really out of range
            watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);

            watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);

            // starting watching for advertisements
            watcher.Start();

            string msg = "自动发现设备中..";

            this.MessAgeChanged(MsgType.NotifyTxt, msg);
        }
        private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
        {
            BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress).Completed = (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    if (asyncInfo.GetResults() == null)
                    {
                        //this.MessAgeChanged(MsgType.NotifyTxt, "没有得到结果集");
                    }
                    else
                    {
                        BluetoothLEDevice currentDevice = asyncInfo.GetResults();

                        Boolean contain = false;

                        foreach (BluetoothLEDevice device in DeviceList)//过滤重复的设备
                        {
                            if (device.DeviceId == currentDevice.DeviceId)
                            {
                                contain = true;
                            }
                        }
                        if (!contain)
                        {
                            byte[] _Bytes1 = BitConverter.GetBytes(currentDevice.BluetoothAddress);

                            Array.Reverse(_Bytes1);

                            this.DeviceList.Add(currentDevice);

                            this.MessAgeChanged(MsgType.NotifyTxt, "发现设备:" + currentDevice.Name + "  address:" + BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower());

                            this.DeviceWatcherChanged(MsgType.BleDevice, currentDevice);
                        }
                    }

                }
            };
        }

        /// <summary>
        /// 停止搜索蓝牙
        /// </summary>
        public void StopBleDeviceWatcher()
        {
            this.watcher.Stop();
        }
        /// <summary>
        /// 获取发现的蓝牙设备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async Task DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
        {
            this.MessAgeChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);

            this.Matching(args.Id);
        }
        /// <summary>
        /// 停止搜索蓝牙设备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
        {
            string msg = "自动发现设备停止";

            this.MessAgeChanged(MsgType.NotifyTxt, msg);
        }
        /// <summary>
        /// 匹配
        /// </summary>
        /// <param name="Device"></param>
        public void StartMatching(BluetoothLEDevice Device)
        {
            this.CurrentDevice = Device;
        }
        /// <summary>
        /// 获取蓝牙服务
        /// </summary>
        public void FindService()
        {
            this.CurrentDevice.GetGattServicesAsync().Completed = (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    var services = asyncInfo.GetResults().Services;
                    this.MessAgeChanged(MsgType.NotifyTxt, "GattServices size=" + services.Count);
                    foreach (GattDeviceService ser in services)
                    {
                        this.GattDeviceServiceAdded(ser);
                    }

                }
            };
        }

        /// <summary>
        /// 获取特性
        /// </summary>
       // [Obsolete]
        public void FindCharacteristic(GattDeviceService gattDeviceService)
        {
            gattDeviceService.GetCharacteristicsAsync().Completed = (asyncInfo, asyncStatus) =>
            {
                // gattDeviceService.GetCharacteristicsAsync();
                if (asyncStatus == AsyncStatus.Completed)
                {
                    var character = asyncInfo.GetResults().Characteristics;

                    this.MessAgeChanged(MsgType.NotifyTxt, "GattCharacteristics size=" + character.Count);

                    foreach (GattCharacteristic c in character)
                    {
                        this.CharacteristicAdded(c);
                    }
                    this.MessAgeChanged(MsgType.NotifyTxt, "获取特征码收集完毕");

                }
            };
        }
        /// <summary>
        /// 获取操作
        /// </summary>
        /// <returns></returns>
        public void SetOpteron(GattCharacteristic gattCharacteristic)
        {
            byte[] _Bytes1 = BitConverter.GetBytes(this.CurrentDevice.BluetoothAddress);

            Array.Reverse(_Bytes1);

            this.CurrentDeviceMAC = BitConverter.ToString(_Bytes1, 2, 6).Replace('-', ':').ToLower();

            string msg = "正在连接设备<" + this.CurrentDeviceMAC + ">..";

            this.MessAgeChanged(MsgType.NotifyTxt, msg);

            if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Write)
            {
                this.CurrentWriteCharacteristic = gattCharacteristic;
            }
            if (gattCharacteristic.CharacteristicProperties == GattCharacteristicProperties.Notify)
            {
                this.CurrentNotifyCharacteristic = gattCharacteristic;
            }
            if ((uint)gattCharacteristic.CharacteristicProperties == 26)
            {

            }
            //这里是难点 返回一个enum枚举
            if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Write | GattCharacteristicProperties.Notify))
            {
                this.CurrentWriteCharacteristic = gattCharacteristic;

                this.CurrentNotifyCharacteristic = gattCharacteristic;

                this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;

                this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;

                this.CurrentDevice.ConnectionStatusChanged += this.CurrentDevice_ConnectionStatusChanged;

                this.EnableNotifications(CurrentNotifyCharacteristic);
            }
            if (gattCharacteristic.CharacteristicProperties == (GattCharacteristicProperties.Notify | GattCharacteristicProperties.Read | GattCharacteristicProperties.WriteWithoutResponse))
            {
                this.CurrentWriteCharacteristic = gattCharacteristic;

                this.CurrentNotifyCharacteristic = gattCharacteristic;

                this.CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;

                this.CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;

                this.EnableNotifications(CurrentNotifyCharacteristic);
            }
        }
        /// <summary>
        /// 清空蓝牙设备列表
        /// </summary>
        /// <returns></returns>
        public void ClearDeviceList()
        {
            this.DeviceList.Clear();
        }
        /// <summary>
        /// 搜索到的蓝牙设备
        /// </summary>
        /// <returns></returns>
        private void Matching(string Id)
        {
            try
            {
                BluetoothLEDevice.FromIdAsync(Id).Completed = (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        BluetoothLEDevice bleDevice = asyncInfo.GetResults();
                        this.DeviceList.Add(bleDevice);
                        this.DeviceWatcherChanged(MsgType.BleDevice, bleDevice);
                    }
                };
            }
            catch (Exception e)
            {
                string msg = "没有发现设备" + e.ToString();
                this.MessAgeChanged(MsgType.NotifyTxt, msg);
                this.StartBleDeviceWatcher();
            }
        }
        /// <summary>
        /// 主动断开连接
        /// </summary>
        /// <returns></returns>
        public void Dispose()
        {

            CurrentDeviceMAC = null;
            CurrentService?.Dispose();
            CurrentDevice?.Dispose();
            CurrentDevice = null;
            CurrentService = null;
            CurrentWriteCharacteristic = null;
            CurrentNotifyCharacteristic = null;
            MessAgeChanged(MsgType.NotifyTxt, "主动断开连接");
        }
        private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
        {
            if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
            {
                string msg = "设备已断开,自动重连";
                MessAgeChanged(MsgType.NotifyTxt, msg);
                if (!asyncLock)
                {
                    asyncLock = true;
                    this.CurrentDevice.Dispose();
                    this.CurrentDevice = null;
                    CurrentService = null;
                    CurrentWriteCharacteristic = null;
                    CurrentNotifyCharacteristic = null;
                    SelectDeviceFromIdAsync(CurrentDeviceMAC);
                }
            }
            else
            {
                string msg = "设备已连接";
                MessAgeChanged(MsgType.NotifyTxt, msg);
            }
        }
        /// <summary>
        /// 按MAC地址直接组装设备ID查找设备
        /// </summary>
        public void  SelectDeviceFromIdAsync(string MAC)
        {
            CurrentDeviceMAC = MAC;
            CurrentDevice = null;
            BluetoothAdapter.GetDefaultAsync().Completed = (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;
                    Matching(Id);
                }
            };
        }
        /// <summary>
        /// 设置特征对象为接收通知对象
        /// </summary>
        /// <param name="characteristic"></param>
        /// <returns></returns>
        public void EnableNotifications(GattCharacteristic characteristic)
        {
            string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;
            this.MessAgeChanged(MsgType.NotifyTxt, msg);
            characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = (asyncInfo, asyncStatus) =>
            {
                if (asyncStatus == AsyncStatus.Completed)
                {
                    GattCommunicationStatus status = asyncInfo.GetResults();
                    if (status == GattCommunicationStatus.Unreachable)
                    {
                        msg = "设备不可用";
                        this.MessAgeChanged(MsgType.NotifyTxt, msg);
                        if (CurrentNotifyCharacteristic != null && !asyncLock)
                        {
                            this.EnableNotifications(CurrentNotifyCharacteristic);
                        }
                    }
                    asyncLock = false;
                    msg = "设备连接状态" + status;
                    this.MessAgeChanged(MsgType.NotifyTxt, msg);
                }
            };
        }

        /// <summary>
        /// 接受到蓝牙数据
        /// </summary>
        private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {
            byte[] data;
            CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
            string str = BitConverter.ToString(data);
            this.MessAgeChanged(MsgType.BleData, str, data);
        }
        /// <summary>
        /// 发送数据接口
        /// </summary>
        /// <returns></returns>
        public void Write(byte[] data)
        {
            if (CurrentWriteCharacteristic != null)
            {
                CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse).Completed = (asyncInfo, asyncStatus) =>
                {
                    if (asyncStatus == AsyncStatus.Completed)
                    {
                        GattCommunicationStatus a = asyncInfo.GetResults();
                        string str = "发送数据:" + BitConverter.ToString(data) + " State : " + a;
                        this.MessAgeChanged(MsgType.BleData, str, data);
                    }
                };
            }
        }
    }
}

BLE入门https://blog.csdn.net/ccslff/article/details/51599148
参考作品:https://blog.csdn.net/Vishera/article/details/116592725?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163722453016780271969375%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163722453016780271969375&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-5-116592725.first_rank_v2_pc_rank_v29&utm_term=c%23%E4%BD%8E%E8%83%BD%E8%80%97%E8%93%9D%E7%89%99&spm=1018.2226.3001.4187

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

️公子

有帮助的,请多支持我哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值