bluetooth.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. function inArray(arr, key, val) {
  2. for (let i = 0; i < arr.length; i++) {
  3. if (arr[i][key] === val) {
  4. return i
  5. }
  6. }
  7. return -1
  8. }
  9. // ArrayBuffer转16进度字符串示例
  10. function ab2hex(buffer) {
  11. const hexArr = Array.prototype.map.call(
  12. new Uint8Array(buffer),
  13. function (bit) {
  14. return ('00' + bit.toString(16)).slice(-2)
  15. }
  16. )
  17. return hexArr.join('')
  18. }
  19. Page({
  20. onShareAppMessage() {
  21. return {
  22. title: '蓝牙',
  23. path: 'page/API/pages/bluetooth/bluetooth'
  24. }
  25. },
  26. data: {
  27. devices: [],
  28. connected: false,
  29. chs: [],
  30. },
  31. onUnload() {
  32. this.closeBluetoothAdapter()
  33. },
  34. openBluetoothAdapter() {
  35. wx.openBluetoothAdapter({
  36. success: (res) => {
  37. console.log('openBluetoothAdapter success', res)
  38. this.startBluetoothDevicesDiscovery()
  39. },
  40. fail: (res) => {
  41. if (res.errCode === 10001) {
  42. wx.showModal({
  43. title: '错误',
  44. content: '未找到蓝牙设备, 请打开蓝牙后重试。',
  45. showCancel: false
  46. })
  47. wx.onBluetoothAdapterStateChange(function (res) {
  48. console.log('onBluetoothAdapterStateChange', res)
  49. if (res.available) {
  50. this.startBluetoothDevicesDiscovery()
  51. }
  52. })
  53. }
  54. }
  55. })
  56. },
  57. getBluetoothAdapterState() {
  58. wx.getBluetoothAdapterState({
  59. success: (res) => {
  60. console.log('getBluetoothAdapterState', res)
  61. if (res.discovering) {
  62. this.onBluetoothDeviceFound()
  63. } else if (res.available) {
  64. this.startBluetoothDevicesDiscovery()
  65. }
  66. }
  67. })
  68. },
  69. startBluetoothDevicesDiscovery() {
  70. if (this._discoveryStarted) {
  71. return
  72. }
  73. this._discoveryStarted = true
  74. wx.startBluetoothDevicesDiscovery({
  75. allowDuplicatesKey: true,
  76. success: (res) => {
  77. console.log('startBluetoothDevicesDiscovery success', res)
  78. this.onBluetoothDeviceFound()
  79. },
  80. })
  81. },
  82. stopBluetoothDevicesDiscovery() {
  83. wx.stopBluetoothDevicesDiscovery({
  84. complete: () => {
  85. this._discoveryStarted = false
  86. }
  87. })
  88. },
  89. onBluetoothDeviceFound() {
  90. wx.onBluetoothDeviceFound((res) => {
  91. res.devices.forEach(device => {
  92. if (!device.name && !device.localName) {
  93. return
  94. }
  95. const foundDevices = this.data.devices
  96. const idx = inArray(foundDevices, 'deviceId', device.deviceId)
  97. const data = {}
  98. if (idx === -1) {
  99. data[`devices[${foundDevices.length}]`] = device
  100. } else {
  101. data[`devices[${idx}]`] = device
  102. }
  103. this.setData(data)
  104. })
  105. })
  106. },
  107. createBLEConnection(e) {
  108. const ds = e.currentTarget.dataset
  109. const deviceId = ds.deviceId
  110. const name = ds.name
  111. wx.showLoading()
  112. wx.createBLEConnection({
  113. deviceId,
  114. success: () => {
  115. this.setData({
  116. connected: true,
  117. name,
  118. deviceId,
  119. })
  120. this.getBLEDeviceServices(deviceId)
  121. },
  122. complete() {
  123. wx.hideLoading()
  124. }
  125. })
  126. this.stopBluetoothDevicesDiscovery()
  127. },
  128. closeBLEConnection() {
  129. wx.closeBLEConnection({
  130. deviceId: this.data.deviceId
  131. })
  132. this.setData({
  133. connected: false,
  134. chs: [],
  135. canWrite: false,
  136. })
  137. },
  138. getBLEDeviceServices(deviceId) {
  139. wx.getBLEDeviceServices({
  140. deviceId,
  141. success: (res) => {
  142. for (let i = 0; i < res.services.length; i++) {
  143. if (res.services[i].isPrimary) {
  144. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
  145. return
  146. }
  147. }
  148. }
  149. })
  150. },
  151. getBLEDeviceCharacteristics(deviceId, serviceId) {
  152. wx.getBLEDeviceCharacteristics({
  153. deviceId,
  154. serviceId,
  155. success: (res) => {
  156. console.log('getBLEDeviceCharacteristics success', res.characteristics)
  157. for (let i = 0; i < res.characteristics.length; i++) {
  158. const item = res.characteristics[i]
  159. if (item.properties.read) {
  160. wx.readBLECharacteristicValue({
  161. deviceId,
  162. serviceId,
  163. characteristicId: item.uuid,
  164. })
  165. }
  166. if (item.properties.write) {
  167. this.setData({
  168. canWrite: true
  169. })
  170. this._deviceId = deviceId
  171. this._serviceId = serviceId
  172. this._characteristicId = item.uuid
  173. this.writeBLECharacteristicValue()
  174. }
  175. if (item.properties.notify || item.properties.indicate) {
  176. wx.notifyBLECharacteristicValueChange({
  177. deviceId,
  178. serviceId,
  179. characteristicId: item.uuid,
  180. state: true,
  181. })
  182. }
  183. }
  184. },
  185. fail(res) {
  186. console.error('getBLEDeviceCharacteristics', res)
  187. }
  188. })
  189. // 操作之前先监听,保证第一时间获取数据
  190. wx.onBLECharacteristicValueChange((characteristic) => {
  191. const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
  192. const data = {}
  193. if (idx === -1) {
  194. data[`chs[${this.data.chs.length}]`] = {
  195. uuid: characteristic.characteristicId,
  196. value: ab2hex(characteristic.value)
  197. }
  198. } else {
  199. data[`chs[${idx}]`] = {
  200. uuid: characteristic.characteristicId,
  201. value: ab2hex(characteristic.value)
  202. }
  203. }
  204. // data[`chs[${this.data.chs.length}]`] = {
  205. // uuid: characteristic.characteristicId,
  206. // value: ab2hex(characteristic.value)
  207. // }
  208. this.setData(data)
  209. })
  210. },
  211. writeBLECharacteristicValue() {
  212. // 向蓝牙设备发送一个0x00的16进制数据
  213. const buffer = new ArrayBuffer(1)
  214. const dataView = new DataView(buffer)
  215. // eslint-disable-next-line
  216. dataView.setUint8(0, Math.random() * 255 | 0)
  217. wx.writeBLECharacteristicValue({
  218. deviceId: this._deviceId,
  219. serviceId: this._deviceId,
  220. characteristicId: this._characteristicId,
  221. value: buffer,
  222. })
  223. },
  224. closeBluetoothAdapter() {
  225. wx.closeBluetoothAdapter()
  226. this._discoveryStarted = false
  227. },
  228. })