windows BLE编程 net winform 连接蓝牙4.0
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 = ;
- //特性通知类型通知启用
- 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, , ).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 > )
- {
- 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 > )
- {
- 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 > )
- {
- 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
windows BLE编程 net winform 连接蓝牙4.0的更多相关文章
- [转]windows BLE编程 net winform 连接蓝牙4.0
本文转自:https://www.cnblogs.com/webtojs/p/9675956.html winform 程序调用Windows.Devices.Bluetoot API 实现windo ...
- Windows 10下怎么远程连接 Ubuntu 16.0.4(方案二)
使用TeamViewer实现远程桌面连接 背景: 有些朋友反映,借助Ubuntu自带的桌面共享工具desktop sharing会有不再同一网端下出现连接不稳定或者掉线的问题,那么现在我们就可以借助第 ...
- Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)
前言: 公司因为用Ruby做开发,所有适用了Ubuntu系统,但是自己笔记本是W10,又不想装双系统,搭建开发环境,便想到倒不如自己远程操控公司电脑,这样在家的时候也可以处理一些问题.故此便有了下面的 ...
- 蓝牙4.0(包含BLE)简介
1. BLE (低功耗蓝牙)简介 国际蓝牙联盟( BT-SIG,TI 是 企业成员之一)通过的一个标准蓝牙无线协议. 主要的新特性是在蓝牙标准版本上添加了4.0 蓝牙规范 (2010 年6 月 ...
- iOS蓝牙BLE4.0通信功能
概述 iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下. 详细 代码下载:ht ...
- 基于蓝牙4.0(Bluetooth Low Energy)胎压监测方案设计
基于一种新的蓝牙技术——蓝牙4.0(Bluetooth Low Energy)新型的胎压监测系统(TPMS)的设计方案.鉴于蓝牙4.0(Bluetooth Low Energy)的低成本.低功耗.高稳 ...
- Android项目实战(三十四):蓝牙4.0 BLE 多设备连接
最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...
- android4.3 蓝牙BLE编程
一.蓝牙4.0简介 蓝牙4.0标准包含两个蓝牙标准,准确的说,是一个双模的标准,它包含传统蓝牙部分(也有称之为经典蓝牙Classic Bluetooth)和低功耗蓝牙部分(Bluetooth Low ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
随机推荐
- P3258 [JLOI2014]松鼠的新家 (简单的点差分)
https://www.luogu.org/problemnew/show/P3258 注意开始和最后结尾 #include <bits/stdc++.h> #define read re ...
- MFC在对话框中嵌入对话框
在对话框中嵌入子对话框 代码 m_childDlg = new CChildDlg(); m_childDlg->Create(IDD_CHILD_DIALOG,AfxGetApp()-> ...
- Paper | 块分割信息 + 压缩视频质量增强
目录 1. 亮点 2. 网络 3. Mask 及其融合 4. 结论 论文:Enhancing HEVC Compressed Videos with a Partition-Masked Convol ...
- JSP的分页技术
在实际应用中,如果从数据库中查询的记录特别的多,甚至超过了显示屏的显示范围,这个时候可将结果进行分页显示. 假设总记录数为intRowCount,每页显示的数量为inPageSize,总页数为intP ...
- C# Autofac集成之Framework WebAPI
Web API 2集成需要Autofac.WebApi2 NuGet包. Web API集成需要Autofac.WebApi NuGet包. Web API集成为控制器,模型绑定器和操作过滤器提供了依 ...
- 【手记】解决VS发布asp.net项目报错“该项目中不存在目标GatherAllFilesToPublish”及后续问题
办法在最后. 用VS2017打开一个以前用VS2010写的asp.net项目后,设置好发布选项(发布到文件夹),发布的时候报错如图: 搜索一番,找到的办法是: 在项目文件(xxx.csproj)中,在 ...
- Java学习笔记51(综合项目:家庭记账系统)
javaEE的开发模式 1.什么是模式 模式在开发过程中总结出的“套路”,总结出的一套约定俗成的设计模式 2.javaEE经历的模式 model1模式: 技术组成:jsp+javaBean model ...
- ElasticSearch权威指南学习(文档)
什么是文档 在Elasticsearch中,文档(document)这个术语有着特殊含义.它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasti ...
- 自动化测试之数据库操作pymysql
1.下载并导入pymysql 2.配置参数连接mysql db = pymysql.connect(**config) config = { 'host': str(host), 主机地址 'user ...
- 哥们,你真以为你会做这道JVM面试题?
有关Java虚拟机类加载机制相关的文章一搜一大把,笔者这里也不必再赘述一遍了. 笔者这里捞出一道code题要各位大佬来把玩把玩,如果你一眼就看出了端倪,那么恭喜你,你可以下山了: public cla ...