解决 安卓小程序蓝牙 重连失败的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决 安卓小程序蓝牙 重连失败的问题相关的知识,希望对你有一定的参考价值。

参考技术A 小程序蓝牙连接问题在苹果手机上一直没问题,都是秒连,但是在安卓手机上就遇到各种坑,这里简单记录一下我所遇到的问题 以及解决方案:

原因很简单,就是我搜索到需要连接的蓝牙之后,就调用了 stopBluetoothDevicesDiscovery 这个方法来关闭搜索周边蓝牙的功能,然后就 提示 10012 连接超时的错误

微信小程序蓝牙连接硬件设备并进行通讯,小程序蓝牙因距离异常断开自动重连,js实现crc校验位

一、小程序实现搜索蓝牙:
注意:comtl是我封装的工具函数,无关紧要,实际项目中可能用不到:

const comtl = require('../../utils/commontool')
const app = getApp() // 拿到全局定义的变量,需要在app.js中:App(globalData:  params: ''),params为全局变量名
let timerid = 0 // 定时器id
Page(
  data: 
    datas:[], // 所有蓝牙数据
    deviceId:'', // 蓝牙设备 id
    bluename:'', // 蓝牙设备 name
    serviceuuid:'', // 选中蓝牙设备的服务uuid截取字符串
    serviceId:'', // 服务id ,uuid
    characteristicNotifyId:'', // 读数据的特征值id
    characteristicWriteId:'', // 写数据的特征值id
    timerStat:true
  ,
  searchDevice: function()  // 蓝牙初始化
    clearInterval(timerid)
    wx.vibrateShort()
    let _this = this
    let arr = []
    this.setData(
      datas:arr
    )
    wx.openBluetoothAdapter(
      success: function(res) 
        _this.getBluetoothState()
      ,
      fail: function(res) 
       comtl.toast('蓝牙初始化失败','error',2000)
      
    )
  ,
  getBluetoothState: function()  // 获取本地蓝牙适配器状态
    let _this = this
    wx.getBluetoothAdapterState(
      success: function(res) 
        _this.findBleDevices()
      ,
      fail: function(e) 
        comtl.toast('获取本机蓝牙适配器状态失败','error',2000)
      
    )
  ,
  findBleDevices: function()  // 搜索蓝牙
    comtl.openloading('搜索蓝牙...',false)
    let _this = this
    wx.startBluetoothDevicesDiscovery(
      success: function(res) 
        _this.onBluetoothDeviceFound()
      ,
      fail: function(res) 
        comtl.toast('搜索蓝牙失败','error',2000)
      
    )
  ,
  onBluetoothDeviceFound: function()  // 监听搜索到新设备的事件
    let _this = this
    wx.onBluetoothDeviceFound(function(res) 
      _this.getBluetoothDevices()
    )
  ,
  getBluetoothDevices: function() 
    let _this = this
    wx.getBluetoothDevices( //获取在蓝牙模块生效期间所有搜索到的蓝牙设备,包括已经和本机处于连接状态的设备
      success: function(res) 
        _this.setData(
          datas:res.devices
        )
      ,
      fail: function(res) 
        comtl.toast('获取蓝牙设备失败','error',2000)
      
    )
  ,
  clickBlueToolHandle: function(e) 
    wx.vibrateShort()
    let _this = this
    wx.closeBLEConnection( // 断开与蓝牙低功耗设备的连接
      deviceId:_this.data.deviceId
    )
    wx.stopBluetoothDevicesDiscovery() //停止搜寻附近的蓝牙外围设备
    if(e)
      let deviceId = e.currentTarget.dataset.deid;
      let bluename = e.currentTarget.dataset.bluename;
      let serviceuuid = e.currentTarget.dataset.serviceuuid;
      this.setData(
        deviceId:deviceId,
        bluename:bluename,
        serviceuuid:serviceuuid
      )
    
    //蓝牙连接
    wx.createBLEConnection( // 连接与蓝牙低功耗设备的连接
      deviceId: _this.data.deviceId,
      timeout:5000,
      success: function(res) 
        clearInterval(timerid)
        _this.stopBluetooth() //停止搜索
        _this.monitorIsBreak();
        _this.getBLEDeviceServices();    //获取服务
      ,
      fail: function(res) 
        wx.hideLoading()
        comtl.toast('连接低功耗蓝牙失败','error',2000)
      ,
      complete: function ()
        comtl.toast('不支持','error',2000)
      
    )
  ,
  monitorIsBreak() // 监听异常断开
    let _this = this
    wx.onBLEConnectionStateChange(function(res) 
      if(!res.connected)  // 判断是否为断开连接
        _this.timerConnect()// 开启定时器
        wx.vibrateLong()
        comtl.toast('蓝牙已断开','error',5000)
        _this.setData(
          timerStat:false
        )
      else
        _this.setData(
          timerStat:true
        )
      
   )
  ,
  stopBluetooth()  //停止蓝牙搜索
    wx.stopBluetoothDevicesDiscovery(
      success: function(res) 
        comtl.closeloading() // 关闭停止搜索遮挡层
        comtl.toast('停止蓝牙搜索','success',2000)
      ,
      fail: function(res) 
        comtl.toast('停止蓝牙搜索失败','error',2000)
      
    )
  ,
  getBLEDeviceServices: function()  //获取蓝牙低功耗设备所有服务uuid
    let services = [];
    let _this = this;
    wx.getBLEDeviceServices(
      deviceId: _this.data.deviceId,
      success: function(res) 
        services = res.services
        if (services.length <= 0) 
          comtl.toast('没有服务','error',2000)
          return
        
        //循环获取serviceId
        for (let x in services)  //x = index
          if (services[x].uuid.indexOf(_this.data.serviceuuid) >= 0) 
            //找到有效的UUID
            _this.setData(
              serviceId:services[x].uuid
            )
            _this.getBLEDeviceCharacteristics()
            break
          
        
      ,
      fail: function(res) 
        comtl.toast('获取设备服务失败','error',2000)
      
    )
  ,
  getBLEDeviceCharacteristics: function()  //获取蓝牙低功耗设备某个服务中所有特征
    let charactArray = [];
    let _this = this;
    wx.getBLEDeviceCharacteristics(
      deviceId: this.data.deviceId,
      serviceId: this.data.serviceId, // 这个是上面那个UUID
      success: function(res) 
        charactArray = res.characteristics;
        if (charactArray.length <= 0) 
          comtl.toast('获取特征值失败','error',2000)
          return
        
        //charactArray  也就是  res.characteristics 这个里面有能读数据的 能写数据的 要分着用
        for (var x in charactArray) 
          //写数据   
          if (charactArray[x].properties.write) 
            _this.setData(
              characteristicWriteId:charactArray[x].uuid
            )
          
          //读数据
          if (charactArray[x].properties.notify) 
            _this.setData(
              characteristicNotifyId:charactArray[x].uuid
            )
          
        
        app.params = _this.data
        wx.switchTab(
          url: '../home/home'
        )
      ,
      fail: function(res) 
        comtl.toast('蓝牙不支持','error',2000)
      
    )
  ,
  onShareAppMessage: function(res) 
    return 
      title: 'F3000X',
      path: 'pages/searchbuletool/searchbuletool',
      success: function(res) 
    
  ,
  onShow()
    clearInterval(timerid)
  ,
  timerConnect() //定时器自动重新连接(因距离导致断开重新连接)
    let _this = this
    if (_this.data.timerStat) 
     timerid = setInterval(()=>
       _this.clickBlueToolHandle() 
      ,5000)
    
  
)

二、连接某蓝牙设备
将datas:[]中的蓝牙数据遍历渲染到某个wxml页面上,点击某个设备的数据即可连接,需要注意的是,你自己的小程序需要支持某蓝牙设备,不然即使连接上蓝牙也无法操作设备,如:

const comtl = require('../../utils/commontool')
const app = getApp()
let dataString = ''
Page(
  data: 
    datas:[], // 所有蓝牙数据
    deviceId:'', // 蓝牙设备 id
    bluename:'', // 蓝牙设备 name
    serviceuuid:'', // 选中蓝牙设备的服务uuid截取字符串
    serviceId:'', // 服务id ,uuid
    characteristicNotifyId:'', // 读数据的特征值id
    characteristicWriteId:'', // 写数据的特征值id
    domdatas:, // 页面数值数据
    domunit:, // 页面单位数据
    transdat:'', //转换后的值
    transdat1:'', //转换后的值
    transdat2:'', //转换后的值
    timerId:0, // 定时器id
    isGoRest:false
  ,
  onLoad() 
    let isExist = wx.getStorageSync('history')
    if(isExist === '' || isExist === undefined)
      wx.setStorageSync('history',[])
    
  ,
  redatat: function(dt)  // 读数据开始
    if(dt.BtchFlowCount)
      this.setData(
        domdatas:dt,
        transdat: this.filter(this.data.domdatas.ReadyConst,this.data.domunit.dotted),
        transdat1: this.filter(this.data.domdatas.MinutFlowCount,this.data.domunit.dotted),
        transdat2: this.filter(this.data.domdatas.BtchFlowCount,this.data.domunit.dotted)
      )
    else if(dt.dotted)
      this.setData(
        domunit:dt
      )
    
    let _this = this
    wx.notifyBLECharacteristicValueChange(
      deviceId: this.data.deviceId,
      serviceId: this.data.serviceId,
      characteristicId: this.data.characteristicNotifyId, 
      state: true,
      success: function(res) 
        _this.onBLECharacteristicValueChange();
      
    )
    dataString = ''
  ,
  onBLECharacteristicValueChange: function()  // 监听蓝牙特征值变化
    wx.onBLECharacteristicValueChange(function(res) 
      dataString += comtl.ab2hex(res.value)
    )
  ,
  writedata: function(hex)  // 写数据
    wx.writeBLECharacteristicValue(
      deviceId: this.data.deviceId,
      serviceId: this.data.serviceId,
      characteristicId: this.data.characteristicWriteId,
      value: comtl.str2ab(hex),
      success: function(res) ,
      fail: function(res) 
    )
  ,
  startTimer() // 定时获取数据:
    let ids = setInterval(()=>
      this.readUnit()
    ,100)
    setTimeout(()=>
      clearInterval(ids)
    ,800)
    let timerid = setInterval(()=>
      this.readData()
    ,1000)
    this.setData(
      timerId:timerid
    )
  ,
  readData() // 读数值数据:
    let domdat = comtl.transformData(dataString)
    this.redatat(domdat)
    this.writedata('01030001001E9402')
  ,
  readUnit() // 读单位:
    let domdat = comtl.transformUnit(dataString)
    this.redatat(domdat)
    this.writedata('01035003000624C8')
  ,
  starttap()
    wx.vibrateShort()
    this.writedata('011020070001020014862A')
    setTimeout(()=>
      if(this以上是关于解决 安卓小程序蓝牙 重连失败的问题的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序蓝牙连接硬件设备并进行通讯,小程序蓝牙因距离异常断开自动重连,js实现crc校验位

熊晨沣蓝牙实战--小程序蓝牙连接2.0

微信(支付宝)小程序蓝牙4.0线上项目

小程序webSocket使用心得

小程序 蓝牙连接

微信小程序蓝牙模块BLE开发说明基础知识