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

先贴图,回头来完善代码

源码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Windows.Devices.Bluetooth;
  7. using Windows.Devices.Bluetooth.GenericAttributeProfile;
  8. using Windows.Devices.Enumeration;
  9. using Windows.Foundation;
  10. using Windows.Security.Cryptography;
  11.  
  12. namespace BLECode
  13. {
  14. public class BluetoothLECode
  15. {
  16. //存储检测的设备MAC。
  17. public string CurrentDeviceMAC { get; set; }
  18. //存储检测到的设备。
  19. public BluetoothLEDevice CurrentDevice { get; set; }
  20. //存储检测到的主服务。
  21. public GattDeviceService CurrentService { get; set; }
  22. //存储检测到的写特征对象。
  23. public GattCharacteristic CurrentWriteCharacteristic { get; set; }
  24. //存储检测到的通知特征对象。
  25. public GattCharacteristic CurrentNotifyCharacteristic { get; set; }
  26.  
  27. public string ServiceGuid { get; set; }
  28.  
  29. public string WriteCharacteristicGuid { get; set; }
  30. public string NotifyCharacteristicGuid { get; set; }
  31.  
  32. private const int CHARACTERISTIC_INDEX = ;
  33. //特性通知类型通知启用
  34. private const GattClientCharacteristicConfigurationDescriptorValue CHARACTERISTIC_NOTIFICATION_TYPE = GattClientCharacteristicConfigurationDescriptorValue.Notify;
  35.  
  36. private Boolean asyncLock = false;
  37.  
  38. private DeviceWatcher deviceWatcher;
  39.  
  40. //定义一个委托
  41. public delegate void eventRun(MsgType type, string str,byte[] data=null);
  42. //定义一个事件
  43. public event eventRun ValueChanged;
  44.  
  45. public BluetoothLECode(string serviceGuid, string writeCharacteristicGuid, string notifyCharacteristicGuid)
  46. {
  47. ServiceGuid = serviceGuid;
  48. WriteCharacteristicGuid = writeCharacteristicGuid;
  49. NotifyCharacteristicGuid = notifyCharacteristicGuid;
  50. }
  51.  
  52. public void StartBleDeviceWatcher()
  53. {
  54.  
  55. string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
  56. string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";
  57.  
  58. deviceWatcher =
  59. DeviceInformation.CreateWatcher(
  60. aqsAllBluetoothLEDevices,
  61. requestedProperties,
  62. DeviceInformationKind.AssociationEndpoint);
  63.  
  64. // Register event handlers before starting the watcher.
  65. deviceWatcher.Added += DeviceWatcher_Added;
  66. deviceWatcher.Stopped += DeviceWatcher_Stopped;
  67. deviceWatcher.Start();
  68. string msg = "自动发现设备中..";
  69.  
  70. ValueChanged(MsgType.NotifyTxt, msg);
  71. }
  72.  
  73. private void DeviceWatcher_Stopped(DeviceWatcher sender, object args)
  74. {
  75. string msg = "自动发现设备停止";
  76. ValueChanged(MsgType.NotifyTxt, msg);
  77. }
  78.  
  79. private void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
  80. {
  81. ValueChanged(MsgType.NotifyTxt, "发现设备:" + args.Id);
  82. if (args.Id.EndsWith(CurrentDeviceMAC))
  83. {
  84. Matching(args.Id);
  85. }
  86.  
  87. }
  88.  
  89. /// <summary>
  90. /// 按MAC地址查找系统中配对设备
  91. /// </summary>
  92. /// <param name="MAC"></param>
  93. public async Task SelectDevice(string MAC)
  94. {
  95. CurrentDeviceMAC = MAC;
  96. CurrentDevice = null;
  97. DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()).Completed = async (asyncInfo, asyncStatus) =>
  98. {
  99. if (asyncStatus == AsyncStatus.Completed)
  100. {
  101. DeviceInformationCollection deviceInformation = asyncInfo.GetResults();
  102. foreach (DeviceInformation di in deviceInformation)
  103. {
  104. await Matching(di.Id);
  105. }
  106. if (CurrentDevice == null)
  107. {
  108. string msg = "没有发现设备";
  109. ValueChanged(MsgType.NotifyTxt, msg);
  110. StartBleDeviceWatcher();
  111. }
  112. }
  113. };
  114. }
  115. /// <summary>
  116. /// 按MAC地址直接组装设备ID查找设备
  117. /// </summary>
  118. /// <param name="MAC"></param>
  119. /// <returns></returns>
  120. public async Task SelectDeviceFromIdAsync(string MAC)
  121. {
  122. CurrentDeviceMAC = MAC;
  123. CurrentDevice = null;
  124. BluetoothAdapter.GetDefaultAsync().Completed = async (asyncInfo, asyncStatus) =>
  125. {
  126. if (asyncStatus == AsyncStatus.Completed)
  127. {
  128. BluetoothAdapter mBluetoothAdapter = asyncInfo.GetResults();
  129. byte[] _Bytes1 = BitConverter.GetBytes(mBluetoothAdapter.BluetoothAddress);//ulong转换为byte数组
  130. Array.Reverse(_Bytes1);
  131. string macAddress = BitConverter.ToString(_Bytes1, , ).Replace('-', ':').ToLower();
  132. string Id = "BluetoothLE#BluetoothLE" + macAddress + "-" + MAC;
  133. await Matching(Id);
  134. }
  135.  
  136. };
  137.  
  138. }
  139.  
  140. private async Task Matching(string Id)
  141. {
  142.  
  143. try
  144. {
  145. BluetoothLEDevice.FromIdAsync(Id).Completed = async (asyncInfo, asyncStatus) =>
  146. {
  147. if (asyncStatus == AsyncStatus.Completed)
  148. {
  149. BluetoothLEDevice bleDevice = asyncInfo.GetResults();
  150. //在当前设备变量中保存检测到的设备。
  151. CurrentDevice = bleDevice;
  152. await Connect();
  153.  
  154. }
  155. };
  156. }
  157. catch (Exception e)
  158. {
  159. string msg = "没有发现设备" + e.ToString();
  160. ValueChanged(MsgType.NotifyTxt, msg);
  161. StartBleDeviceWatcher();
  162. }
  163.  
  164. }
  165.  
  166. private async Task Connect()
  167. {
  168. string msg = "正在连接设备<" + CurrentDeviceMAC + ">..";
  169. ValueChanged(MsgType.NotifyTxt, msg);
  170. CurrentDevice.ConnectionStatusChanged += CurrentDevice_ConnectionStatusChanged;
  171. await SelectDeviceService();
  172.  
  173. }
  174.  
  175. /// <summary>
  176. /// 主动断开连接
  177. /// </summary>
  178. /// <returns></returns>
  179. public void Dispose()
  180. {
  181.  
  182. CurrentDeviceMAC = null;
  183. CurrentService?.Dispose();
  184. CurrentDevice?.Dispose();
  185. CurrentDevice = null;
  186. CurrentService = null;
  187. CurrentWriteCharacteristic = null;
  188. CurrentNotifyCharacteristic = null;
  189. ValueChanged(MsgType.NotifyTxt, "主动断开连接");
  190.  
  191. }
  192.  
  193. private void CurrentDevice_ConnectionStatusChanged(BluetoothLEDevice sender, object args)
  194. {
  195. if (sender.ConnectionStatus == BluetoothConnectionStatus.Disconnected && CurrentDeviceMAC != null)
  196. {
  197. string msg = "设备已断开,自动重连";
  198. ValueChanged(MsgType.NotifyTxt, msg);
  199. if (!asyncLock)
  200. {
  201. asyncLock = true;
  202. CurrentDevice.Dispose();
  203. CurrentDevice = null;
  204. CurrentService = null;
  205. CurrentWriteCharacteristic = null;
  206. CurrentNotifyCharacteristic = null;
  207. SelectDeviceFromIdAsync(CurrentDeviceMAC);
  208. }
  209.  
  210. }
  211. else
  212. {
  213. string msg = "设备已连接";
  214. ValueChanged(MsgType.NotifyTxt, msg);
  215. }
  216. }
  217. /// <summary>
  218. /// 按GUID 查找主服务
  219. /// </summary>
  220. /// <param name="characteristic">GUID 字符串</param>
  221. /// <returns></returns>
  222. public async Task SelectDeviceService()
  223. {
  224. Guid guid = new Guid(ServiceGuid);
  225. CurrentDevice.GetGattServicesForUuidAsync(guid).Completed = (asyncInfo, asyncStatus) =>
  226. {
  227. if (asyncStatus == AsyncStatus.Completed)
  228. {
  229. try
  230. {
  231. GattDeviceServicesResult result = asyncInfo.GetResults();
  232. string msg = "主服务=" + CurrentDevice.ConnectionStatus;
  233. ValueChanged(MsgType.NotifyTxt, msg);
  234. if (result.Services.Count > )
  235. {
  236. CurrentService = result.Services[CHARACTERISTIC_INDEX];
  237. if (CurrentService != null)
  238. {
  239. asyncLock = true;
  240. GetCurrentWriteCharacteristic();
  241. GetCurrentNotifyCharacteristic();
  242.  
  243. }
  244. }
  245. else
  246. {
  247. msg = "没有发现服务,自动重试中";
  248. ValueChanged(MsgType.NotifyTxt, msg);
  249. SelectDeviceService();
  250. }
  251. }
  252. catch (Exception e)
  253. {
  254. ValueChanged(MsgType.NotifyTxt, "没有发现服务,自动重试中");
  255. SelectDeviceService();
  256.  
  257. }
  258. }
  259. };
  260. }
  261.  
  262. /// <summary>
  263. /// 设置写特征对象。
  264. /// </summary>
  265. /// <returns></returns>
  266. public async Task GetCurrentWriteCharacteristic()
  267. {
  268.  
  269. string msg = "";
  270. Guid guid = new Guid(WriteCharacteristicGuid);
  271. CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
  272. {
  273. if (asyncStatus == AsyncStatus.Completed)
  274. {
  275. GattCharacteristicsResult result = asyncInfo.GetResults();
  276. msg = "特征对象=" + CurrentDevice.ConnectionStatus;
  277. ValueChanged(MsgType.NotifyTxt, msg);
  278. if (result.Characteristics.Count > )
  279. {
  280. CurrentWriteCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
  281. }
  282. else
  283. {
  284. msg = "没有发现特征对象,自动重试中";
  285. ValueChanged(MsgType.NotifyTxt, msg);
  286. await GetCurrentWriteCharacteristic();
  287. }
  288. }
  289. };
  290. }
  291.  
  292. /// <summary>
  293. /// 发送数据接口
  294. /// </summary>
  295. /// <param name="characteristic"></param>
  296. /// <param name="data"></param>
  297. /// <returns></returns>
  298. public async Task Write(byte[] data)
  299. {
  300. if (CurrentWriteCharacteristic != null)
  301. {
  302. CurrentWriteCharacteristic.WriteValueAsync(CryptographicBuffer.CreateFromByteArray(data), GattWriteOption.WriteWithResponse);
  303. }
  304.  
  305. }
  306.  
  307. /// <summary>
  308. /// 设置通知特征对象。
  309. /// </summary>
  310. /// <returns></returns>
  311. public async Task GetCurrentNotifyCharacteristic()
  312. {
  313. string msg = "";
  314. Guid guid = new Guid(NotifyCharacteristicGuid);
  315. CurrentService.GetCharacteristicsForUuidAsync(guid).Completed = async (asyncInfo, asyncStatus) =>
  316. {
  317. if (asyncStatus == AsyncStatus.Completed)
  318. {
  319. GattCharacteristicsResult result = asyncInfo.GetResults();
  320. msg = "特征对象=" + CurrentDevice.ConnectionStatus;
  321. ValueChanged(MsgType.NotifyTxt, msg);
  322. if (result.Characteristics.Count > )
  323. {
  324. CurrentNotifyCharacteristic = result.Characteristics[CHARACTERISTIC_INDEX];
  325. CurrentNotifyCharacteristic.ProtectionLevel = GattProtectionLevel.Plain;
  326. CurrentNotifyCharacteristic.ValueChanged += Characteristic_ValueChanged;
  327. await EnableNotifications(CurrentNotifyCharacteristic);
  328.  
  329. }
  330. else
  331. {
  332. msg = "没有发现特征对象,自动重试中";
  333. ValueChanged(MsgType.NotifyTxt, msg);
  334. await GetCurrentNotifyCharacteristic();
  335. }
  336. }
  337. };
  338. }
  339.  
  340. /// <summary>
  341. /// 设置特征对象为接收通知对象
  342. /// </summary>
  343. /// <param name="characteristic"></param>
  344. /// <returns></returns>
  345. public async Task EnableNotifications(GattCharacteristic characteristic)
  346. {
  347. string msg = "收通知对象=" + CurrentDevice.ConnectionStatus;
  348. ValueChanged(MsgType.NotifyTxt, msg);
  349.  
  350. characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(CHARACTERISTIC_NOTIFICATION_TYPE).Completed = async (asyncInfo, asyncStatus) =>
  351. {
  352. if (asyncStatus == AsyncStatus.Completed)
  353. {
  354. GattCommunicationStatus status = asyncInfo.GetResults();
  355. if (status == GattCommunicationStatus.Unreachable)
  356. {
  357. msg = "设备不可用";
  358. ValueChanged(MsgType.NotifyTxt, msg);
  359. if (CurrentNotifyCharacteristic != null && !asyncLock)
  360. {
  361. await EnableNotifications(CurrentNotifyCharacteristic);
  362. }
  363. }
  364. asyncLock = false;
  365. msg = "设备连接状态" + status;
  366. ValueChanged(MsgType.NotifyTxt, msg);
  367. }
  368. };
  369. }
  370.  
  371. private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
  372. {
  373. byte[] data;
  374. CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
  375. string str = BitConverter.ToString(data);
  376. ValueChanged(MsgType.BLEData,str, data);
  377.  
  378. }
  379. }
  380.  
  381. public enum MsgType
  382. {
  383. NotifyTxt,
  384. BLEData
  385. }
  386. }

调用方式:

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

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

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

windows BLE编程 net winform 连接蓝牙4.0的更多相关文章

  1. [转]windows BLE编程 net winform 连接蓝牙4.0

    本文转自:https://www.cnblogs.com/webtojs/p/9675956.html winform 程序调用Windows.Devices.Bluetoot API 实现windo ...

  2. Windows 10下怎么远程连接 Ubuntu 16.0.4(方案二)

    使用TeamViewer实现远程桌面连接 背景: 有些朋友反映,借助Ubuntu自带的桌面共享工具desktop sharing会有不再同一网端下出现连接不稳定或者掉线的问题,那么现在我们就可以借助第 ...

  3. Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)

    前言: 公司因为用Ruby做开发,所有适用了Ubuntu系统,但是自己笔记本是W10,又不想装双系统,搭建开发环境,便想到倒不如自己远程操控公司电脑,这样在家的时候也可以处理一些问题.故此便有了下面的 ...

  4. 蓝牙4.0(包含BLE)简介

    1. BLE   (低功耗蓝牙)简介 国际蓝牙联盟( BT-SIG,TI  是 企业成员之一)通过的一个标准蓝牙无线协议. 主要的新特性是在蓝牙标准版本上添加了4.0 蓝牙规范 (2010 年6 月 ...

  5. iOS蓝牙BLE4.0通信功能

    概述 iOS蓝牙BLE4.0通信功能,最近刚学的苹果,为了实现蓝牙门锁的项目,找了一天学习了下蓝牙的原理,亲手测试了一次蓝牙的通信功能,结果成功了,那么就把我学习的东西分享一下. 详细 代码下载:ht ...

  6. 基于蓝牙4.0(Bluetooth Low Energy)胎压监测方案设计

    基于一种新的蓝牙技术——蓝牙4.0(Bluetooth Low Energy)新型的胎压监测系统(TPMS)的设计方案.鉴于蓝牙4.0(Bluetooth Low Energy)的低成本.低功耗.高稳 ...

  7. Android项目实战(三十四):蓝牙4.0 BLE 多设备连接

    最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. ------------------------------------------- ...

  8. android4.3 蓝牙BLE编程

    一.蓝牙4.0简介 蓝牙4.0标准包含两个蓝牙标准,准确的说,是一个双模的标准,它包含传统蓝牙部分(也有称之为经典蓝牙Classic Bluetooth)和低功耗蓝牙部分(Bluetooth Low ...

  9. Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

随机推荐

  1. P3258 [JLOI2014]松鼠的新家 (简单的点差分)

    https://www.luogu.org/problemnew/show/P3258 注意开始和最后结尾 #include <bits/stdc++.h> #define read re ...

  2. MFC在对话框中嵌入对话框

    在对话框中嵌入子对话框 代码 m_childDlg = new CChildDlg(); m_childDlg->Create(IDD_CHILD_DIALOG,AfxGetApp()-> ...

  3. Paper | 块分割信息 + 压缩视频质量增强

    目录 1. 亮点 2. 网络 3. Mask 及其融合 4. 结论 论文:Enhancing HEVC Compressed Videos with a Partition-Masked Convol ...

  4. JSP的分页技术

    在实际应用中,如果从数据库中查询的记录特别的多,甚至超过了显示屏的显示范围,这个时候可将结果进行分页显示. 假设总记录数为intRowCount,每页显示的数量为inPageSize,总页数为intP ...

  5. C# Autofac集成之Framework WebAPI

    Web API 2集成需要Autofac.WebApi2 NuGet包. Web API集成需要Autofac.WebApi NuGet包. Web API集成为控制器,模型绑定器和操作过滤器提供了依 ...

  6. 【手记】解决VS发布asp.net项目报错“该项目中不存在目标GatherAllFilesToPublish”及后续问题

    办法在最后. 用VS2017打开一个以前用VS2010写的asp.net项目后,设置好发布选项(发布到文件夹),发布的时候报错如图: 搜索一番,找到的办法是: 在项目文件(xxx.csproj)中,在 ...

  7. Java学习笔记51(综合项目:家庭记账系统)

    javaEE的开发模式 1.什么是模式 模式在开发过程中总结出的“套路”,总结出的一套约定俗成的设计模式 2.javaEE经历的模式 model1模式: 技术组成:jsp+javaBean model ...

  8. ElasticSearch权威指南学习(文档)

    什么是文档 在Elasticsearch中,文档(document)这个术语有着特殊含义.它特指最顶层结构或者根对象(root object)序列化成的JSON数据(以唯一ID标识并存储于Elasti ...

  9. 自动化测试之数据库操作pymysql

    1.下载并导入pymysql 2.配置参数连接mysql db = pymysql.connect(**config) config = { 'host': str(host), 主机地址 'user ...

  10. 哥们,你真以为你会做这道JVM面试题?

    有关Java虚拟机类加载机制相关的文章一搜一大把,笔者这里也不必再赘述一遍了. 笔者这里捞出一道code题要各位大佬来把玩把玩,如果你一眼就看出了端倪,那么恭喜你,你可以下山了: public cla ...