Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

小程序之蓝牙的使用 #7

Open
yangrenmu opened this issue May 4, 2019 · 1 comment
Open

小程序之蓝牙的使用 #7

yangrenmu opened this issue May 4, 2019 · 1 comment

Comments

@yangrenmu
Copy link
Owner

初始化蓝牙

使用蓝牙之前,首先要先初始化蓝牙(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)
  }
})
@nadirvishun
Copy link

有个问题:

           // 蓝牙未打开,监听蓝牙状态
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              that.startBluetoothDevicesDiscovery()
            }
          })

如果要监听蓝牙状态,当停止搜索时stopBluetoothDevicesDiscovery,这个也会触发导致刚停止搜索,这里又会打开了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants