小程序之蓝牙的使用

2,949 阅读4分钟

初始化蓝牙

使用蓝牙之前,首先要先初始化蓝牙(openBluetoothAdapter),之后才能调用蓝牙的各种api。初始化状态分为两种: 初始化成功:这时可以去搜索蓝牙设备(startBluetoothDevicesDiscovery)。 初始化失败:这个时候需要提示用户打开蓝牙,同时监听蓝牙的状态(onBluetoothAdapterStateChange),当蓝牙打开时,去搜索设备。

  openBluetoothAdapter() {
    const that = this
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        // 初始化成功,去搜索设备
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        if (res.errCode === 10001) {
          // 蓝牙未打开,监听蓝牙状态
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              that.startBluetoothDevicesDiscovery()
            }
          })
        }
      }
    })
  }

搜索蓝牙设备

开始搜索附近的蓝牙设备(startBluetoothDevicesDiscovery),该操作比较耗费资源,建议在连接到蓝牙设备后,手动停止搜索。

  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    // 开始搜索蓝牙设备,allowDuplicatesKey,会重复搜索同一设备
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
    })
  }

获取蓝牙设备

获取蓝牙设备有两个api。

  • onBluetoothDeviceFound:获取新发现的设备,将startBluetoothDevicesDiscovery中的allowDuplicatesKey设置为true时,该方法重复上报同一蓝牙设备。
  • getBluetoothDevices:获取已经发现的蓝牙设备列表,该方法获取的蓝牙设备数量跟搜索时间有关系,一般在开始搜索蓝牙设备后,延时一段时间在调用该方法。
  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:连接蓝牙设备,基本上到这,蓝牙设备就连接上了。为了避免一个设备多个连接实例,一般和closeBLEConnection成对调用。在连接成功后,一般需要调用stopBluetoothDevicesDiscovery,停止蓝牙的搜索。

  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    // 开始连接蓝牙设备
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
      }
    })
    // 在连接蓝牙设备后,停止搜索蓝牙。
    this.stopBluetoothDevicesDiscovery()
  }

停止搜索蓝牙设备

stopBluetoothDevicesDiscovery: 在蓝牙设备连接成功后,需要停止搜索蓝牙设备。

  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  }

监听蓝牙设备的连接状态

onBLEConnectionStateChange:监听蓝牙设备的连接状态,包括蓝牙设备的丢失,断开,可以在该方法中进行处理这些连接后发生的异常情况。

wx.onBLEConnectionStateChange(function (res) {
  // 该方法回调中可以用于处理连接意外断开等异常情况
  console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
})

获取蓝牙设备服务

在连接上蓝牙设备后,我们想要的还是跟蓝牙进行通信,或读取蓝牙设备的数据,或写数据到蓝牙设备。首先需要获取蓝牙设备的服务信息。

  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:根据蓝牙的服务信息,获取可以跟蓝牙进行通信的特征值。一般使用notify或indicate为true、read或write为true的特征值。

启用蓝牙设备的通知功能

notifyBLECharacteristicValueChange: 启用蓝牙设备的通知功能,该方法需要蓝牙设备的特征值 notify 或 indicate 为 true。只有在在蓝牙设备启用该功能,才能监听到蓝牙设备的数据变化。

获取蓝牙设备的数据

onBLECharacteristicValueChange:监听蓝牙设备的数据变化,当蓝牙设备的数据变化时,可以获取相应变化后的数据。需要在启用蓝牙设备的通知功能后才能使用。

写数据到蓝牙设备

writeBLECharacteristicValue:写数据到蓝牙设备,需要特征值的write为true

  // 获取蓝牙设备的特征值
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        for (let i = 0; i < res.characteristics.length; i++) {
          let 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
            // 写数据到蓝牙设备
            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)
        }
      }
      this.setData(data)
    })
  }
  // 写数据到蓝牙设备
  writeBLECharacteristicValue() {
    // 向蓝牙设备发送一个0x00的16进制数据
    let buffer = new ArrayBuffer(1)
    let dataView = new DataView(buffer)
    dataView.setUint8(0, Math.random() * 255 | 0)
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
    })
  }

断开蓝牙设备的连接

closeBLEConnection:断开与蓝牙设备的连接

  closeBLEConnection() {
    // 断开蓝牙设备的连接
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
    })
  }

关闭蓝牙模块

closeBluetoothAdapter: 当蓝牙使用完成后,关闭蓝牙模块,释放系统资源。

// 关闭蓝牙模块
wx.closeBluetoothAdapter({
  success(res) {
    console.log(res)
  }
})