小程式之藍芽的使用

rreennnn發表於2019-05-04

初始化藍芽

使用藍芽之前,首先要先初始化藍芽(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)
  }
})
複製程式碼

相關文章