小程序连接蓝牙流程

本文档详细记录了在微信小程序中实现蓝牙设备连接和数据传输过程中遇到的问题及解决方案,包括Android与iOS系统的差异,如蓝牙数据包大小限制、蓝牙MTU设置在某些设备上的失效以及数据类型的处理等。同时,介绍了如何处理蓝牙数据的接收和转换,确保在不同平台上的兼容性。
摘要由CSDN通过智能技术生成

目前踩过的坑:微信需要打开蓝牙设置,并开启蓝牙,部分安卓手机需要打开手机定位。android手机接收的蓝牙数据包不超过20个字节,但ios基本上没有限制。setBLEMTU方法在 nova 7上不能使用,一直报 internal fail 错误。因为本次需要蓝牙传输的数据比较多, android手机一次只能接收到一半数据,需要再次点击设备的蓝牙数据传输数据按钮,才能获取到全部数据。但是ios一次就能接收到全部数据。蓝牙数据是ArrayBuffer类型,小程序不能打印,要进行16进制处理。

    openBluetoothAdapter() {
      let that = this
      wx.openBluetoothAdapter({
        success: (res) => {
          console.log('openBluetoothAdapter success', res)
          that.startBluetoothDevicesDiscovery()
        },
        fail: (res) => {
          console.log('res', res)
          // if (res.errCode === 10001) {
          wx.showModal({
            // title: '蓝牙',
            content: '请开启蓝牙,部分安卓机需要开启定位服务',
            showCancel: false
          })
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              that.startBluetoothDevicesDiscovery()
            }
          })
          // }
        }
      })
    },
    startBluetoothDevicesDiscovery() {
      let that = this
      if (this.data.discover) {
        return
      }
      this.data.discover = true
      wx.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: true,
        success: (res) => {
          console.log('startBluetoothDevicesDiscovery success', res)
          that.onBluetoothDeviceFound()
        },
        fail: (res) => {
          console.log('startBluetoothDevicesDiscovery fail', res)
        }
      })
    },
    onBluetoothDeviceFound() {
      let that = this
      wx.onBluetoothDeviceFound((res) => {
        console.log('onBluetoothDeviceFound', res)
        res.devices.forEach(device => {
          if (!device.name && !device.localName) {
            return
          }
          console.log(device.name)
          if (device.name.indexOf('BL-IC') !== -1) {
            that.setData({
              deviceId: device.deviceId
            })
            that.createBLEConnection(device);
          }
          that.restartBLE()
        })
      })
    },
    restartBLE(){
      if(!this.data.deviceId){
        setTimeout(function(){
          wx.showModal({
            title:'提示',
            content:'蓝牙连接失败,请重新新增检查',
            showCancel:false,
            success(res){
              if (res.confirm) {
                console.log('用户点击确定')
                wx.navigateBack()
              } else if (res.cancel) {
                console.log('用户点击取消')
              }
            }
          })
        },30000)
      }
    },
    createBLEConnection(ds) {
      // const ds = e.currentTarget.dataset
      const deviceId = ds.deviceId
      const name = ds.name
      let that = this
      wx.createBLEConnection({
        deviceId,
        success: (res) => {
          that.setData({
            tip: '设备连接中,请稍等...',
            name,
            deviceId,
          })
          // if (that.data.platform === 'android') {
          //   that.setBLEMTU(deviceId)
          // } else {
            that.getBLEDeviceServices(deviceId)
          // }
        },
        fail: (res) => {
          console.log('createBLEConnection fail', res)
        }
      })
      that.stopBluetoothDevicesDiscovery()
    },
    stopBluetoothDevicesDiscovery() {
      wx.stopBluetoothDevicesDiscovery()
    },
    getBLEDeviceServices(deviceId) {
      let that = this
      wx.getBLEDeviceServices({
        deviceId,
        success: (res) => {
          console.log('getBLEDeviceServices', res)
          let service = res.services.find(item => (item.uuid).toUpperCase().indexOf('FFE0') !== -1)
          if (service) {
            that.getBLEDeviceCharacteristics(deviceId, service.uuid)
          }
        },
        fail: (res) => {
          console.log('getBLEDeviceServices fail', res)
        }
      })
    },
    // ArrayBuffer转16进度字符串示例
    ab2hex(buffer) {
      var hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function (bit) {
          return ('00' + bit.toString(16)).slice(-2)
        }
      )
      return hexArr.join('');
    },
    hextoString(hex) {
      var arr = hex.split("")
      var out = ""
      for (var i = 0; i < arr.length / 2; i++) {
        var tmp = "0x" + arr[i * 2] + arr[i * 2 + 1]
        var charValue = String.fromCharCode(tmp);
        out += charValue
      }
      return out
    },
    getBLEDeviceCharacteristics(deviceId, serviceId) {
      var that = this
      let characteristicId = null
      wx.getBLEDeviceCharacteristics({
        deviceId,
        serviceId,
        success: (res) => {
          console.log('getBLEDeviceCharacteristics success', res.characteristics)
          let characteristic = res.characteristics.find(item => (item.uuid).toUpperCase().indexOf('FFE1') !== -1)
          that.setData({
            tip: '数据传输中,请稍等...',
          })
          characteristicId = characteristic.uuid
          wx.notifyBLECharacteristicValueChange({
            deviceId,
            serviceId,
            characteristicId,
            state: true,
            success: function (res) {
              console.log('notify success', res.errMsg)
            },
            fail: function (res) {
              console.log('notify fail', res.errMsg)
            },
            complete: function (res) {
              console.log('notify complete', res.errMsg)
            },
          })
        },
        fail(res) {
          console.error('getBLEDeviceCharacteristics', res)
        }
      })
      // 操作之前先监听,保证第一时间获取数据
      wx.onBLECharacteristicValueChange((characteristic) => {
        console.log('value', characteristic.value)
        let data = that.data.blData
        let blData = that.hextoString(that.ab2hex(characteristic.value))
        console.log('blData', blData)
        setTimeout(function(){
          console.log('-------',blData)
          if(!blData){
            if(data.indexOf('PR')!==-1){
              // xxx 处理数据
            }
          }
        },3000)
        if (that.data.blData) {
          that.setData({
            blData: data.concat(blData)
          })
        } else {
          that.setData({
            blData
          })
        }
        blData=null
      })
    },
    closeBLEConnection() {
      wx.closeBLEConnection({
        deviceId: this.data.deviceId
      })
    },
    closeBluetoothAdapter() {
      wx.closeBluetoothAdapter()
      this.data.discover = false
    },
    onLoad(){
      this.openBluetoothAdapter()
    },
    onUnload(){
      this.stopBluetoothDevicesDiscovery()
      this.closeBLEConnection()
      this.closeBluetoothAdapter()
    }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值