function inArray(arr, key, val) { for (let i = 0; i < arr.length; i++) { if (arr[i][key] === val) { return i } } return -1 } // ArrayBuffer转16进度字符串示例 function ab2hex(buffer) { const hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return (`00${bit.toString(16)}`).slice(-2) } ) return hexArr.join('') } Page({ onShareAppMessage() { return { title: '蓝牙', path: 'packageAPI/pages/device/bluetooth/bluetooth' } }, data: { theme: 'light', devices: [], connected: false, chs: [], }, onUnload() { this.closeBluetoothAdapter() }, openBluetoothAdapter() { const that = this wx.openBluetoothAdapter({ success: (res) => { console.log('openBluetoothAdapter success', res) that.startBluetoothDevicesDiscovery() }, fail: (res) => { if (res.errCode === 10001) { wx.showModal({ title: '错误', content: '未找到蓝牙设备, 请打开蓝牙后重试。', showCancel: false }) wx.onBluetoothAdapterStateChange(function (res) { if (res && res.available) { that.startBluetoothDevicesDiscovery() } }) } } }) }, getBluetoothAdapterState() { wx.getBluetoothAdapterState({ success: (res) => { console.log('getBluetoothAdapterState', res) if (res.discovering) { this.onBluetoothDeviceFound() } else if (res.available) { this.startBluetoothDevicesDiscovery() } } }) }, startBluetoothDevicesDiscovery() { if (this._discoveryStarted) { return } this._discoveryStarted = true wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, success: (res) => { console.log('startBluetoothDevicesDiscovery success', res) this.onBluetoothDeviceFound() }, }) }, stopBluetoothDevicesDiscovery() { wx.stopBluetoothDevicesDiscovery({ complete: () => { this._discoveryStarted = false } }) }, onBluetoothDeviceFound() { wx.onBluetoothDeviceFound((res) => { res.devices.forEach(device => { if (!device.name && !device.localName) { return } const foundDevices = this.data.devices const idx = inArray(foundDevices, 'deviceId', device.deviceId) const data = {} if (idx === -1) { data[`devices[${foundDevices.length}]`] = device } else { data[`devices[${idx}]`] = device } this.setData(data) }) }) }, createBLEConnection(e) { const ds = e.currentTarget.dataset const deviceId = ds.deviceId const name = ds.name wx.showLoading() wx.createBLEConnection({ deviceId, success: () => { this.setData({ connected: true, name, deviceId, }) this.getBLEDeviceServices(deviceId) }, complete() { wx.hideLoading() } }) this.stopBluetoothDevicesDiscovery() }, closeBLEConnection() { wx.closeBLEConnection({ deviceId: this.data.deviceId }) this.setData({ connected: false, chs: [], canWrite: false, }) }, changeMode() { wx.navigateTo({ url: './slave/slave', }) }, getBLEDeviceServices(deviceId) { wx.getBLEDeviceServices({ deviceId, success: (res) => { for (let i = 0; i < res.services.length; i++) { if (res.services[i].isPrimary) { this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid) return } } } }) }, getBLEDeviceCharacteristics(deviceId, serviceId) { wx.getBLEDeviceCharacteristics({ deviceId, serviceId, success: (res) => { console.log('getBLEDeviceCharacteristics success', res.characteristics) for (let i = 0; i < res.characteristics.length; i++) { const item = res.characteristics[i] if (item.properties.read) { wx.readBLECharacteristicValue({ deviceId, serviceId, characteristicId: item.uuid, }) } if (item.properties.write) { this.setData({ canWrite: true }) this._deviceId = deviceId this._serviceId = serviceId this._characteristicId = item.uuid console.log('write') this.writeBLECharacteristicValue() } if (item.properties.notify || item.properties.indicate) { wx.notifyBLECharacteristicValueChange({ deviceId, serviceId, characteristicId: item.uuid, state: true, }) } } }, fail(res) { console.error('getBLEDeviceCharacteristics', res) } }) // 操作之前先监听,保证第一时间获取数据 wx.onBLECharacteristicValueChange((characteristic) => { const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId) const data = {} if (idx === -1) { data[`chs[${this.data.chs.length}]`] = { uuid: characteristic.characteristicId, value: ab2hex(characteristic.value) } } else { data[`chs[${idx}]`] = { uuid: characteristic.characteristicId, value: ab2hex(characteristic.value) } } wx.showToast({ title: '收到从机数据', }) // data[`chs[${this.data.chs.length}]`] = { // uuid: characteristic.characteristicId, // value: ab2hex(characteristic.value) // } this.setData(data) }) }, writeBLECharacteristicValue() { // 向蓝牙设备发送一个0x00的16进制数据 const buffer = new ArrayBuffer(1) const dataView = new DataView(buffer) // eslint-disable-next-line dataView.setUint8(0, Math.random() * 19| 0) wx.writeBLECharacteristicValue({ deviceId: this._deviceId, serviceId: this._serviceId, characteristicId: this._characteristicId, value: buffer, success() { console.log('writeBLECharacteristicValue: 成功') }, fail() { console.log('writeBLECharacteristicValue: 失败') }, complete() { console.log('writeBLECharacteristicValue: 结束') } }) }, closeBluetoothAdapter() { wx.closeBluetoothAdapter() this._discoveryStarted = false }, onLoad() { this.setData({ theme: wx.getSystemInfoSync().theme || 'light' }) if (wx.onThemeChange) { wx.onThemeChange(({theme}) => { this.setData({theme}) }) } } })