蓝牙控制阀小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
11 KiB

3 years ago
  1. class Bluetooth {
  2. // 构造函数
  3. constructor() {
  4. this.isOpenBle = false;
  5. this.isStop = false;
  6. this.deviceList = [];
  7. this.deviceId = "";
  8. this.serviceId = "";
  9. this.readId = "";
  10. this.writeId = "";
  11. this.notifyId = "";
  12. this.indicateId = "";
  13. this.valueChangeData = {};
  14. // this.openBluetoothAdapter();
  15. }
  16. // 弹出框封装
  17. showToast(title) {
  18. uni.showToast({
  19. title: title,
  20. icon: 'none',
  21. 'duration': 2000
  22. });
  23. }
  24. // 判断初始化蓝牙状态
  25. initTypes(code, errMsg) {
  26. switch (code) {
  27. case 10000:
  28. this.showToast('未初始化蓝牙适配器');
  29. break;
  30. case 10001:
  31. this.showToast('请打开蓝牙后重试');
  32. break;
  33. case 10002:
  34. this.showToast('没有找到指定设备');
  35. break;
  36. case 10003:
  37. this.showToast('连接失败');
  38. break;
  39. case 10004:
  40. this.showToast('没有找到指定服务');
  41. break;
  42. case 10005:
  43. this.showToast('没有找到指定特征值');
  44. break;
  45. case 10006:
  46. this.showToast('当前连接已断开');
  47. break;
  48. case 10007:
  49. this.showToast('当前特征值不支持此操作');
  50. break;
  51. case 10008:
  52. this.showToast('其余所有系统上报的异常');
  53. break;
  54. case 10009:
  55. this.showToast('Android 系统特有,系统版本低于 4.3 不支持 BLE');
  56. break;
  57. default:
  58. this.showToast(errMsg);
  59. }
  60. }
  61. // 初始化蓝牙模块
  62. openBluetoothAdapter(callback) {
  63. uni.openBluetoothAdapter({
  64. success: res => {
  65. console.log('初始化>>>res', res)
  66. this.isOpenBle = true;
  67. this.initTypes(0, "初始化蓝牙模块成功");
  68. if (typeof callback == "function")
  69. this.onBluetoothDeviceFound(callback);
  70. },
  71. fail: err => {
  72. console.log('初始化>>>err', err)
  73. this.initTypes(err.errCode);
  74. }
  75. });
  76. }
  77. // 关闭蓝牙模块
  78. closeBluetoothAdapter() {
  79. uni.closeBluetoothAdapter({
  80. success: res => {
  81. console.log(res)
  82. }
  83. });
  84. }
  85. // 获取本机蓝牙适配器状态
  86. getBluetoothAdapterState() {
  87. return new Promise((resolve, reject) => {
  88. uni.getBluetoothAdapterState({
  89. success: res => {
  90. console.log(JSON.stringify(res));
  91. // this.adapterState = res;
  92. resolve(res);
  93. },
  94. fail: err => {
  95. console.log('获取本机蓝牙适配器状态失败,错误码:' + err.errCode);
  96. reject(err);
  97. }
  98. });
  99. });
  100. }
  101. // 搜索蓝牙设备
  102. startBluetoothDevicesDiscovery() {
  103. if (!this.isOpenBle) {
  104. this.showToast(`初始化蓝牙模块失败`)
  105. return;
  106. }
  107. let self = this;
  108. uni.showLoading({
  109. title: '蓝牙搜索中'
  110. })
  111. return new Promise((resolve, reject) => {
  112. setTimeout(() => {
  113. uni.startBluetoothDevicesDiscovery({
  114. success: res => {
  115. resolve(res)
  116. },
  117. fail: res => {
  118. self.showToast(`搜索设备失败` + JSON.stringify(err));
  119. reject(err);
  120. }
  121. })
  122. }, 300);
  123. });
  124. }
  125. // 停止搜索蓝牙设备
  126. stopBluetoothDevicesDiscovery() {
  127. uni.stopBluetoothDevicesDiscovery({
  128. fail: err => {
  129. this.showToast(`停止搜索蓝牙设备失败` + JSON.stringify(err));
  130. },
  131. complete: res => {
  132. uni.hideLoading();
  133. }
  134. })
  135. }
  136. // 发现外围设备
  137. onBluetoothDeviceFound(callback) {
  138. console.log('发现外围设备')
  139. // 侦听发现的设备
  140. uni.onBluetoothDeviceFound(devices => {
  141. console.log('开始监听寻找到新设备的事件');
  142. this.getBluetoothDevices(callback);
  143. });
  144. }
  145. // 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
  146. getBluetoothDevices(callback) {
  147. uni.getBluetoothDevices({
  148. success: res => {
  149. // self.newDeviceLoad = false;
  150. console.log('获取蓝牙设备成功:', res);
  151. this.deviceList = res.devices;
  152. callback();
  153. },
  154. fail: err => {
  155. console.log('获取蓝牙设备错误,错误码:', err);
  156. if (err.errCode !== 0) {
  157. this.initTypes(err.errCode);
  158. }
  159. }
  160. });
  161. }
  162. //获取蓝牙设备所有服务(service)
  163. getBLEDeviceServices(callback) {
  164. let _serviceList = [];
  165. let deviceId = this.deviceId;
  166. let self = this;
  167. setTimeout(() => { //解决app不能得到服务的bug,500-1000
  168. uni.getBLEDeviceServices({
  169. deviceId,
  170. success: res => {
  171. for (let service of res.services) {
  172. if (service.isPrimary) {
  173. _serviceList.push(service);
  174. }
  175. }
  176. // console.log("_serviceList: " + JSON.stringify(_serviceList));
  177. if (typeof callback == "function") callback(_serviceList)
  178. },
  179. fail: err => {
  180. self.showToast(`获取设备Services失败:` + JSON.stringify(err));
  181. },
  182. complete: res => {
  183. uni.hideLoading();
  184. }
  185. });
  186. }, 500);
  187. }
  188. //获取蓝牙设备某个服务中所有特征值(characteristic)
  189. getBLEDeviceCharacteristics(serviceId) {
  190. let deviceId = this.deviceId;
  191. this.serviceId = serviceId;
  192. let self = this;
  193. return new Promise((resolve, reject) => {
  194. uni.getBLEDeviceCharacteristics({
  195. deviceId,
  196. serviceId,
  197. success: res => {
  198. for (let _obj of res.characteristics) {
  199. //获取readId
  200. if (_obj.properties.read) {
  201. self.readId = _obj.uuid;
  202. } else {
  203. self.readId = ''
  204. }
  205. // uni.setStorageSync('readId', self.readId);
  206. //获取writeId
  207. if (_obj.properties.write) {
  208. self.writeId = _obj.uuid;
  209. } else {
  210. self.writeId = ''
  211. }
  212. // uni.setStorageSync('writeId', self.writeId);
  213. //获取notifyId
  214. if (_obj.properties.notify) {
  215. self.notifyId = _obj.uuid;
  216. } else {
  217. self.notifyId = ''
  218. }
  219. // uni.setStorageSync('notifyId', self.notifyId);
  220. //获取indicateId
  221. if (_obj.properties.indicate) {
  222. self.indicateId = _obj.uuid;
  223. } else {
  224. self.indicateId = ''
  225. }
  226. // uni.setStorageSync('indicateId', self.indicateId);
  227. }
  228. let result = {
  229. 'readId': self.readId,
  230. 'writeId': self.writeId,
  231. 'notifyId': self.notifyId,
  232. 'indicateId': self.indicateId
  233. };
  234. resolve(result)
  235. },
  236. fail: err => {
  237. self.showToast(`getBLEDeviceCharacteristics` + JSON.stringify(err));
  238. reject(err);
  239. }
  240. })
  241. });
  242. }
  243. // 连接低功耗蓝牙
  244. createBLEConnection(deviceId, callback) {
  245. let self = this;
  246. this.deviceId = deviceId;
  247. this.isStop = false;
  248. uni.showLoading({
  249. mask: true,
  250. title: '设备连接中,请稍候...'
  251. })
  252. uni.createBLEConnection({
  253. deviceId,
  254. success: res => {
  255. if (typeof callback == "function") callback();
  256. // this.onBLEConnectionStateChange(callback)
  257. },
  258. fail: err => {
  259. self.showToast(`连接蓝牙设备失败` + JSON.stringify(err));
  260. },
  261. complete: res => {
  262. uni.hideLoading();
  263. }
  264. })
  265. }
  266. // 断开与低功耗蓝牙设备的连接
  267. closeBLEConnection() {
  268. let deviceId = this.deviceId;
  269. this.isStop = true;
  270. uni.closeBLEConnection({
  271. deviceId,
  272. success(res) {
  273. console.log(res)
  274. }
  275. })
  276. }
  277. // 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
  278. onBLEConnectionStateChange(callback) {
  279. uni.onBLEConnectionStateChange(res => {
  280. // 该方法回调中可以用于处理连接意外断开等异常情况
  281. console.log(`蓝牙连接状态 -------------------------->`);
  282. console.log(JSON.stringify(res));
  283. if (!res.connected) {
  284. if (this.isStop) return;
  285. console.log('断开低功耗蓝牙成功:');
  286. // this.searchLoad = false;
  287. // this.equipment = [];
  288. // this.servicesData = [];
  289. // this.characteristicsData = [];
  290. this.valueChangeData = {};
  291. this.showToast('已经断开当前蓝牙连接');
  292. if (typeof callback == "function") callback();
  293. }
  294. });
  295. }
  296. // 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
  297. onBLECharacteristicValueChange() {
  298. // 必须在这里的回调才能获取
  299. uni.onBLECharacteristicValueChange(characteristic => {
  300. console.log('监听低功耗蓝牙设备的特征值变化事件成功');
  301. console.log(JSON.stringify(characteristic));
  302. this.valueChangeData = characteristic;
  303. });
  304. }
  305. // 读取低功耗蓝牙设备的特征值的二进制数据值。注意:必须设备的特征值支持 read 才可以成功调用
  306. readBLECharacteristicValue() {
  307. let deviceId = this.deviceId;
  308. let serviceId = this.serviceId;
  309. let characteristicId = this.notifyId;
  310. console.log(deviceId);
  311. console.log(serviceId);
  312. console.log(characteristicId);
  313. uni.readBLECharacteristicValue({
  314. // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
  315. deviceId,
  316. // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
  317. serviceId,
  318. // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
  319. characteristicId,
  320. success: res => {
  321. console.log('读取设备数据值成功');
  322. console.log(JSON.stringify(res));
  323. this.notifyBLECharacteristicValueChange();
  324. },
  325. fail(e) {
  326. console.log('读取设备数据值失败,错误码:' + e.errCode);
  327. if (e.errCode !== 0) {
  328. this.initTypes(e.errCode);
  329. }
  330. }
  331. });
  332. this.onBLECharacteristicValueChange();
  333. }
  334. // 向低功耗蓝牙设备特征值中写入二进制数据
  335. writeBLECharacteristicValue(buffer) {
  336. let deviceId = this.deviceId;
  337. let serviceId = this.serviceId;
  338. let characteristicId = this.notifyId;
  339. // console.log("this: " + JSON.stringify(this));
  340. return new Promise((resolve, reject) => {
  341. uni.writeBLECharacteristicValue({
  342. deviceId,
  343. serviceId,
  344. characteristicId,
  345. value: buffer,
  346. success: res => {
  347. console.log('message发送成功:)', JSON.stringify(res));
  348. resolve(res);
  349. },
  350. fail: err => {
  351. console.log('message发送失败:(', JSON.stringify(err));
  352. reject(err);
  353. }
  354. });
  355. });
  356. }
  357. // 启用低功耗蓝牙设备特征值变化时的 notify 功能
  358. notifyBLECharacteristicValue() {
  359. let deviceId = this.deviceId;
  360. let serviceId = this.serviceId;
  361. let characteristicId = this.notifyId;
  362. uni.notifyBLECharacteristicValueChange({
  363. state: true, // 启用 notify 功能
  364. deviceId,
  365. serviceId,
  366. characteristicId,
  367. success: res => {
  368. uni.onBLECharacteristicValueChange((res) => {
  369. console.log('特征值变化:', res)
  370. });
  371. },
  372. fail: res => {
  373. console.log('notifyBLECharacteristicValueChange 失败:' + res.errMsg);
  374. }
  375. });
  376. }
  377. //若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。
  378. reconnect() {
  379. (async () => {
  380. try {
  381. this.deviceId = this.deviceId || uni.getStorageSync("deviceId");
  382. this.serviceId = this.serviceId || uni.getStorageSync("serviceId");
  383. let result1 = await this.createBLEConnection();
  384. console.log("createBLEConnection: " + JSON.stringify(result1));
  385. let result2 = await this.getBLEDeviceServices();
  386. console.log("getBLEDeviceServices: " + JSON.stringify(result2));
  387. let result3 = await this.getBLEDeviceCharacteristics();
  388. console.log("getBLEDeviceCharacteristics: " + JSON.stringify(result3));
  389. // this.writeId = uni.getStorageSync("writeId");
  390. // this.notifyId = uni.getStorageSync("notifyId");
  391. } catch (err) {
  392. console.log("err: " + JSON.stringify(err));
  393. }
  394. })();
  395. }
  396. }
  397. export default Bluetooth;