123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- 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})
- })
- }
- }
- })
|