微信小程序之蓝牙开发遇到的坑

微信小程序之蓝牙开发遇到的坑

遇到的坑

  • 低版本手机未打开系统定位服务时,可能出现搜索不到蓝牙设备,所以最好在页面中提示用户打开定位服务。

  • 微信需授权蓝牙,在手机设置里面打开,否则使用不了蓝牙。

  • 部分api需延时调用否则安卓手机有问题(startBluetoothDevicesDiscovery,getBluetoothDevices,writeBLECharacteristicValue)

  • 连接蓝牙,实际上可能已经连接上,但是小程序api调用会返回10003连接失败,安卓手机会出现

  • 断开蓝牙,小程序api调用会返回调用成功,实际上并可能没有与设备断开,安卓手机会出现

流程图

使用

1.初始化蓝牙模块

  onLoad: function () {
    let that = this
    that.loadDate();
  },

  loadDate() {
    let that = this;
    //初始化蓝牙模块
    wx.openBluetoothAdapter({
      success: (res) => {
        //获取本机蓝牙适配器状态。
        that.getBluetoothAdapterState()
      },
      fail: (res) => {
        if (res.errCode === 10001) {
          //手机蓝牙未打开,弹出提示框让用户打开
          that.setData({
            bluetoothON: false
          })
          //监听蓝牙适配器状态变化
          wx.onBluetoothAdapterStateChange(function (res) {
            if (res.available) {
              that.setData({
                bluetoothON: true
              })
                //获取本机蓝牙适配器状态。
              that.getBluetoothAdapterState()
            }
          })
        }
      }
    })

  },

2.获取本机蓝牙适配器状态

  //获取本机蓝牙适配器状态。
  getBluetoothAdapterState() {
    var that = this;
    wx.getBluetoothAdapterState({
      success: function (res) {
        that.setData({
          bluetoothON: true
        })
        that.startBluetoothDevicesDiscovery()
      },
      fail(res) {
        console.log(res)
      }
    })
  },

3.搜寻附近的蓝牙外围设备

 //开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery 方法停止搜索。
  startBluetoothDevicesDiscovery() {

    var that = this;
    setTimeout(() => {
      wx.startBluetoothDevicesDiscovery({
        success: function (res) {
          /* 获取蓝牙设备列表 */
          that.getBluetoothDevices()
        },
        fail(res) {
          console.log(res)
        }
      })
    }, 1000)
  },

4.获取搜索到的蓝牙设备列表

 // //获取搜索到的蓝牙设备列表
  getBluetoothDevices() {
    var that = this;
    setTimeout(() => {
      wx.getBluetoothDevices({
        success: function (res) {
          if (res.devices.length > 0) {
            //可使用设备
            let searchDevices = res.devices.filter(item => item.localName && item.localName.startsWith("EFF"));
            //这里根据业务需求找出你想连接的设备,调用connect2Bluetooth
            that.connect2Bluetooth(deviceId)
          } else {
            //没有搜索到设备
            console.log("没有搜索到设备")
          }
        },
        fail(res) {
          console.log(res)
        }
      })
    }, 2000)
  },

5.连接蓝牙

//连接蓝牙
  connect2Bluetooth(deviceId) {
    let that = this;
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        that.setData({
          connected: true,
        })
        //设置蓝牙最大传输单元。需在 wx.createBLEConnection调用成功后调用,mtu 设置范围 (22,512)。安卓5.1以上有效。安卓手机在数据接收限制在20个字节内。苹果手机好像没有限制,可以调用此方法改变大小
        wx.setBLEMTU({
          deviceId: that.data.deviceId,
          mtu: 247,
          success: (res) => {
            console.log("setBLEMTU success>>", res)
          },
          fail: (res) => {
            console.log("setBLEMTU fail>>", res)
           
          }
        })

        /*获取连接设备的service服务 */
        that.getBLEDeviceServices();
        //停止搜索设备
        wx.stopBluetoothDevicesDiscovery()
        //监听蓝牙连接状态
        wx.onBLEConnectionStateChange(function (res) {
          that.setData({
            connected: res.connected
          })
          app.globalData.connected = res.connected
          if (!res.connected) {
            console.log("*******************蓝牙连接已断开*****************")
          }
        })
      },
      fail: function (res) {
        console.log(res)
        log.warn(res)
      }
    })
  },
  1. 获取蓝牙设备的service服务,获取的serviceId有多个要试着连接最终确定哪个是稳定版本的service 获取服务完后获取设备特征值
  getBLEDeviceServices() {
    let that = this;
    wx.getBLEDeviceServices({
      deviceId: that.data.deviceId,
      success: function (res) {
        /* 获取连接设备的所有特征值 */
        for (let i = 0; i < res.services.length; i++) {
        //看你自己项目需求
          if (res.services[i].uuid.toUpperCase().indexOf("FFF0") != -1) {
          //获取设备特征值
            that.getBLEDeviceCharacteristics(res.services[i])
          }
        }

      },
      fail: (res) => {
        console.log(res)
       
      }
    })
  },

7.获取蓝牙设备特征值

  getBLEDeviceCharacteristics(services) {
    let that = this;
    wx.getBLEDeviceCharacteristics({
      deviceId: that.data.deviceId,//// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
      serviceId: services.uuid,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
      success: function (res) {
        for (var i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if (item.properties.read && item.properties.write && (item.properties.notify || item.properties.indicate)) {
            /* 获取蓝牙特征值 */
            wx.readBLECharacteristicValue({
              deviceId: that.data.deviceId,
              serviceId: services.uuid,
              characteristicId: item.uuid,
            })
            app.globalData.deviceId = that.data.deviceId;
            app.globalData.serviceId = services.uuid;
            app.globalData.characteristicId = item.uuid;
            //写数据
          
            // 启用低功耗蓝牙设备特征值变化时的 notify 功能
            that.notifyBLECharacteristicValueChange(that.data.deviceId, services.uuid, res.characteristics[i].uuid)
          }
        }
      },
      fail: function (res) {
        console.log(res)
      }
    })

  },

8.启动notify 蓝牙监听功能

  notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) { // 启用低功耗蓝牙设备特征值变化时的 notify 功能
    var that = this;
    wx.notifyBLECharacteristicValueChange({
      state: true,
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      type: 'notification',//安卓手机需要加这个
      complete(res) {
        console.log(res, '启用低功耗蓝牙设备监听成功')
        //监听获取数据
        wx.onBLECharacteristicValueChange((characteristic) => {
          //设备返回的数据转16进制
          let recBuffer = blueTooth.ab2hex(characteristic.value);
        })
      },
      fail(res) {
        console.log(res, '启用低功耗蓝牙设备监听失败')
      }
    })
  },

工具类 blueTooth.js

//ArrayBuffer转16进制数组示例
function ab2hex(buffer) {
  // let byteRecBuffer =[];
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  
  return hexArr;
}

//往蓝牙写数据
function writeBLECharacteristicValue(str) {
  console.log('写入:' + str)
  let dataBuffer = new ArrayBuffer(str.length)
  let dataView = new DataView(dataBuffer)
  for (var i = 0; i < str.length; i++) {
    dataView.setUint8(i, str[i])
  }

  wx.writeBLECharacteristicValue({
    deviceId: getApp().globalData.deviceId,
    serviceId: getApp().globalData.serviceId,
    characteristicId: getApp().globalData.characteristicId,
    value: dataBuffer,
    success: function (res) {
     console.log("写入成功")
    },
    fail: function (res) {
      console.log('写入失败' + res.errMsg)
    },
  })
}

// 断开设备连接
function closeConnect() {
  if (getApp().globalData.deviceId) {
      wx.closeBLEConnection({
          deviceId: getApp().globalData.deviceId,
          success: function(res) {
            console.log("蓝牙断开连接")
              closeBluetoothAdapter()
          },
          fail(res) {
          }
      })
  } else {
      closeBluetoothAdapter()
  }
}
// 关闭蓝牙模块
function closeBluetoothAdapter() {

  wx.closeBluetoothAdapter({
      success: function(res) {
        console.log("关闭蓝牙模块")
      },
      fail: function(err) {
      }
  })
}

关注可加我微信号

本文地址:https://blog.csdn.net/qq_43643538/article/details/107713496

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐