关于小程序蓝牙连接设备的注意事项

我最近做了一个软硬件结合的项目,通过小程序蓝牙去连接设备,控制锁的开门,总结了一下知识和坑点,希望对大家有点帮助。

首先说我做的这个项目的作用吧

我的项目是一个医疗陪护床,他做初衷是,给长期在医院陪病人家属的人准备的,当病人家属累了,或者困了的时候,就可以关注我的小程序,进入小程序,点击扫码交押金,然后开锁使用,把陪护床拉开,即可使用。

开始介绍我的蓝牙代码和坑点

开锁使用流程代码

1,进入小程序点击开锁,判断手机蓝牙是否开启,这一步最开始的就是判断小程序对手机蓝牙的状态查看。

wx.closeBluetoothAdapter({

    success: res => {

      wx.openBluetoothAdapter({ //初始化 蓝牙模块  成功 和 失败的回调

        success: res => {

          console.log('初始化蓝牙成功' + res)

          this.context.setData({ bluetoothState: true })

          this.getBluetoothAdapterState()  //蓝牙开启成功,执行去查看蓝牙适配情况

        },

        fail: err => {

          console.log(err);

          wx.hideLoading();

          this.context.setData({ bluetoothState: false })

        }

      })

    }

  })


2,手机蓝牙开启成功,进一步判断蓝牙适配是否可用

wx.getBluetoothAdapterState({ //获取本机蓝牙适配器状态 判断用户是否开启蓝牙

      success: res => {

        console.log('蓝牙状态', res)

        //discovering 是否正在搜索设备  available 蓝牙适配器是否可用

        if (res.available == false) { 

          wx.showToast({

            title: '设备无法开启蓝牙连接',

            icon: 'none'

          })

        } else if (res.discovering == false){

            this.startBluetoothDevicesDiscovery()

        } else if (res.available){

          this.startBluetoothDevicesDiscovery()  //蓝牙适配器正常,去执行搜索外围设备

        }

      }

    })


3,开始搜索外围设备,(注意:执行该操作比较浪费资源,在搜索到mac地址成功后停止该操作)

wx.startBluetoothDevicesDiscovery({ //开始搜寻附近的蓝牙外围设备

    services: [this.serviceId], //搜索对应设备的id  以微信硬件平台的蓝牙智能灯为例,主服务的 UUID 是 FEE7。传入这个参数,只搜索主服务 UUID 为 FEE7 的设备

我这边 因为固件底层代码放设定了  serviceId = '0000FFF0-0000-1000-8000-00805F9B34FB'  ,所以只会所搜0000FFF0-0000-1000-8000-00805F9B34FB 的住服务,这边的话类似一个过滤器

    allowDuplicatesKey:false,

    success:res =>{

        console.log(res);

      if (!res.isDiscovering) { //是否在搜索到了设备

        this.getBluetoothAdapterState()

      }else{

        console.log('1');

        / /当时成功时候,就去执行左边监听附近新设备的api

        this.onBluetoothDeviceFound()

      }

    },

    fail: err => {

      console.log(err)

      this.stopBluetoothDevicesDiscovery()

    }

  })


4,这一步是去执行监听附近设备,获取附近设备的devices 结构

   这边是有两个场景,一个位ios,一个安卓,安卓其实通过搜索到devices 里面的mac地直接配对通过,而ios所搜不到mac,只能得到devices 里面uuid,(uuid 可以通过小程序官方提供的一个方法去转成十六进制的数据的mac地址),我这边安卓和ios全部是通过uuid去转为六十机制mac地址,去做配对的,这样一来就不用区分ios和安卓两个场景。

注意,这里设备的mac搜索到之后,一定要执行wx.stopBluetoothDevicesDiscovery() 函数,暂定搜索,不然后台资源很消耗性能的。

functionab2hex(buffer){consthexArr =Array.prototype.map.call(newUint8Array(buffer),function(bit){return('00'+ bit.toString(16)).slice(-2) } )returnhexArr.join('')}

wx.onBluetoothDeviceFound((res) => {

    console.log('搜索到的设备没配对成功有', res)

    res.devices.forEach(device => {

      console.log(device);

      let _advertisData = this.ab2hex(device.advertisData) //得到设备的mac地址

      if (_advertisData == that.advertisData){)

        this.context.connectCallBack('1'); 执行成功对应的回调函数

        wx.setStorageSync('device', device.deviceId)//第一搜索到设备 保存在本地,给关锁的时候使用

        that.deviceId = device.deviceId;

        that.stopBluetoothDevicesDiscovery() //设备已经搜索到,停止搜索

        console.log('设备已经搜索到,停止搜索')

        that.createBLEConnection()

      }

    })

  })

4,获取onBluetoothDeviceFound 通过的 devices 里面 deviceId去连接设备。

连接这边安卓和ios 比较坑的,一次连接失败的概率性特别大,所以为了用户体验上,必须的通过多次循环返回连接,直到连接成功之后,才跳出循环。

我这边的小程序循环的

全局的openFlag=false 在点击开锁的第一个函数里面,执行到createBLEConnection函数的时候,调用openlock函数 里面判断条件不成立就是一直循环值,直到  if (count == 6 && this.openFlag ==false) 时候,这个时候说明6次多连接失败,那么全局openFlag=ftrue 就会 if (count == 6 && this.openFlag == true) 这个终止的条件,跳出界面,这是现阶段最好解决方法,欢迎大家指点。

连接成功之后

createBLEConnection = function () {

    this.openlock(0);

}

openlock=function(count){

    //连接蓝牙之后,就一直是true·

  if (count == 6 && this.openFlag ==false){

    //五次没有连接上,重新卸载蓝牙模块,重新连接

    this.startConnect(this.context,true);

    return false;

  }

  //成立

  if (count == 6 && this.openFlag == true){

    //执行到这一步 一定是deviceId值错误

      wx.showToast({

        title: '连接中断,请重试',

        icon:'none'

      })

      setTimeout(()=>{

        wx.navigateBack({

          data: 1,

        })

      },2000)

        return false;       

    }

  const self = this;

  //500毫秒连接一次,连接一次失败,继续连接,直到10次连接失败,就让他跳转首页

  setTimeout(() => {

    wx.createBLEConnection({

      deviceId: this.deviceId,

    //  deviceId:"a434f199651s",

      success: res => {

        console.log('连接', res)

        if (res.errCode == 0) {

          wx.hideLoading() //连接成功  关闭提示狂

          self.funk = true //防止 连接点击开锁按钮处理

          wx.showToast({

            title: '蓝牙连接设备成功',

            icon: 'none'

          })

          this.getBLEDeviceServices(this.deviceId)

        }

      },

      fail: err => {

        console.log(err)

        console.log(count)

        self.openlock(count+1);

      }

    })

  }, 500)

}

5,连接蓝牙成功之后,这里就是得获取蓝牙所有的服务,这一步为了与建立通讯而准备的

/注意:这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接

wx.getBLEDeviceServices({

    deviceId,

    success: (res) => {

      console.log('服务', res)

      this.getBLEDeviceCharacteristics(this.deviceId, this.serviceId)

    }

  })

6,获取设备的特征值,这一步很重要

 判断是否 write  boolean  该特征值是否支持 write 操作 write 该操作是蓝牙写人二进制数据

  判断是否 notifyboolean该特征值是否支持 notify 操作

  判断是否  indicateboolean该特征值是否支持 indicate 操作

  判断是否  readboolean该特征值是否支持 read 操作

上述判断 notifyboolean indicateboolean readboolean 至少这三种通过,不然写二进制数据的时候,回调失败。

wx.getBLEDeviceCharacteristics({

    deviceId,

    serviceId,

    success: (res) => {

      console.log('特征值', res.characteristics)

      for (let i = 0; i < res.characteristics.length; i++) {

        let item = res.characteristics[i]

        if (item.uuid == this.characteristicId) {

          this.notifyBLECharacteristicValueChange(this.deviceId, this.serviceId, this.characteristicId)

          this.context.connectCallBack()

        }

      }

    },

    fail(res) {

      console.error('getBLEDeviceCharacteristics', res)

    }

  })


7.这个一步是比较重要,向设备蓝牙进入十六进制数据,列表你想要设备做一些动作,比如开锁关锁,一些指令。

wx.writeBLECharacteristicValue({

      deviceId,//设备的 id

      serviceId, //0000FFF0-0000-1000-8000-00805F9B34FB

      characteristicId: this.characteristicId,//0000FFF6-0000-1000-8000-00805F9B34FB

      value: buffer,//蓝牙设备特征值对应的二进制值

      success: res => { resolve(res) },

      fail: err => { reject(err) }

    })

  })


8,启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。注意:必须设备的特征值支持 notify 或者 indicate 才可以成功调用。

另外,必须先启用 notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件

wx.notifyBLECharacteristicValueChange({

    state: true,

    deviceId,

    serviceId,

    characteristicId,

    success: res => {

      console.log('监听成功:', res)

      this.onBLECharacteristicValueChange()

    }

  })


9.监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。

wx.onBLECharacteristicValueChange(res => {

    console.log('123')

    console.log('监听值', this.ab2hex(res.value))

    this.context.callBack(this.ab2hex(res.value))

  })、

10,当你所有功能pai执行完成之后,就去宝珠

wx.stopBluetoothDevicesDiscovery()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容