微信小程序进行蓝牙搜索与连接流程

438 阅读2分钟

最近业务上有这个场景,项目完毕后,简单记录下。

一、前置核心API:

相关文档:developers.weixin.qq.com/miniprogram…

搜索蓝牙:

  • openBluetoothAdapter // 开启蓝牙适配器
  • onBluetoothAdapterStateChange // 监听蓝牙适配器状态
  • onBluetoothDeviceFound // 监听寻找蓝牙设备 (部分安卓需要位置权限)
  • startBluetoothDevicesDiscovery //开启蓝牙搜索功能
  • getBluetoothDevices // 获取已发现的蓝牙设备,包括已经和本机的链接状态的设备

连接蓝牙

  • createBLEConnection //连接蓝牙
  • getBLEDeviceServices //获取蓝牙服务
  • getBLEDeviceCharacteristics //获取蓝牙设备特征值
  • notifyBLECharacteristicValueChange // 开启蓝牙设备订阅
  • writeBLECharacteristicValue // 向设备写入
  • onBLECharacteristicValueChange// 监听蓝牙设备值的变化

二、流程图:

1、获取蓝牙:

开启蓝牙流程.png

2、连接蓝牙

连接蓝牙流程.png

三、核心代码:

1、开启并搜索蓝牙

//开启蓝牙 
const handleBluetoothAdapter = () => {
 Taro.openBluetoothAdapter({
      success(res) {
        // 监听寻找设备事件
        onBluetoothDeviceFound()
        // 开启需按照蓝牙设备
        startBluetoothDevicesDiscovery()
      },
      fail(error) {
        //监听本机蓝牙状态变化的事件
        onBluetoothAdapterStateChange()
        if (error.errCode === 10001) {
          //没有蓝牙权限给出提示
        }
      }
    })
    }
  //监听本机蓝牙状态变化的事件
  const onBluetoothAdapterStateChange = () => {
    Taro.onBluetoothAdapterStateChange(function (res) {
      const available = res.available
      if (available) {
        //重新开蓝牙
        handleBluetoothAdapter()
      }
    })
  }
   // 开启蓝牙搜索功能
  const startBluetoothDevicesDiscovery = () => {
    Taro.startBluetoothDevicesDiscovery({
      // 固定蓝牙UUID
      services: [XXX]
      success() {
        console.log("打开蓝牙搜索功能成功")
      },
      fail(e) {
        console.log("打开蓝牙搜索功能失败", e)
      }
    })
  }
  //监听寻找到新设备的事件
  const onBluetoothDeviceFound = () => {
    Taro.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        // 存储获取到的蓝牙设备End
      })
    })
  }

2、连接蓝牙

// 开始链接蓝牙
  const createBLEConnection = () => {
    Taro.createBLEConnection({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
      deviceId: XXX, //设备ID
      success: function (res) {
        // 进入链接设备的状态
        getBLEDeviceServices()
      }
    })
  }
  // 获取蓝牙服务
  const getBLEDeviceServices = () => {
    Taro.getBLEDeviceServices({
      deviceId:XXX //设备ID
      success(res) {
        getBLEDeviceCharacteristics() //获取特征值
        setTimeout(() => {
          notifyBLECharacteristicValueChange() // 开启订阅
          writeBLECharacteristicValue()    //写入
        }, 1500)
      },
      fail(res) {
        console.log('device services:', res)
      }
    })
  }
//获取特征值
  const getBLEDeviceCharacteristics = () => {
    Taro.getBLEDeviceCharacteristics({
      deviceId: XXX, //设备ID
      serviceId: XXX, // 服务ID
      success(res) {
           // 获取特征值 res.characteristics 
      }
    })
  }
  // 开启订阅值
  const notifyBLECharacteristicValueChange = () => {
    // 取可以notify的特征值
    Taro.notifyBLECharacteristicValueChange({
      state: true, // 启用 notify 功能
      deviceId: XXX, //设备ID
      serviceId: XXX,// 服务ID
      characteristicId: XXX,//特征值ID
      success(res: any) {
        // 监听设备特征值变化
        getonBLECharacteristicValueChange()
      }
    })
  }
  //监听设备特征值变化
  const getonBLECharacteristicValueChange = () => {
    Taro.onBLECharacteristicValueChange((onNotityChangeRes) => {
      // 处理蓝牙返回值
    })
  }

   // 向设备写入值
  const writeBLECharacteristicValue = () => {
     // 取可以write的特征值
    Taro.writeBLECharacteristicValue({
      deviceId: XXX, //设备ID
      serviceId: XXX,// 服务ID
      characteristicId: XXX,//特征值ID
      // 这里的value是ArrayBuffer类型
      value: XXX,
      success(res) {
        console.log('写入成功' +res)
      },
      fail(res) {
        console.log("写入数据失败" + res);
      }
    });
  }

四、注意事项:

  1. 流程完毕后,要及时 closeBluetoothAdapter。

实际场景:整体流程完毕后,onBluetoothDeviceFound 无法再监听到设备信息,重定向页面,重置监听onBluetoothDeviceFound 也无效。

  1. writeBLECharacteristicValue,notifyBLECharacteristicValueChange 两个API的入参中,

    characteristicId 是根据getBLEDeviceCharacteristics 获取的,但是一般会获取到多个Id。区别如下:

    notifyBLECharacteristicValueChange:notify:true

    writeBLECharacteristicValue:write:true

  2. 获取特征值,开启订阅,写入设备信息,这几流程,建议加一些异步延迟,保证流程畅通。

  3. onBluetoothDeviceFound 文档表明,部分安卓机需要位置权限,才可。具体设备未知。