微信小程序> 微信小程序蓝牙模块遇到的坑

微信小程序蓝牙模块遇到的坑

浏览量:502 时间: 来源:i_a_jun

今天第一次写博客,关于微信小程序蓝牙这一块,因为公司项目需要搞一个蓝牙的小程序,而小程序蓝牙模块也是刚出不久,遇到的坑很难解决,经过自己的摸索以及同事的帮忙,终于可以实现获取到蓝牙的数据了。官网:https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxreadblecharacteristicvalueobject
参考文章:http://blog.csdn.net/u010046908/article/details/68924339
这篇文章我不得不说一下,按照这样写,安卓系统是没办法拿到数据的,也就是wx.notifyBLECharacteristicValueChanged这个接口是进不去的。IOS就没试过,因为IOS我没用他的代码,自己写的,也能拿到数据。

测试手机:
手机名称:iPhone 5s  
版本:10.3.1
微信版本:6.5.7
蓝牙:4.0

手机名称:iPhone 6
版本:10.3.1
微信版本:6.5.7
蓝牙:4.0

手机名称:iPhone 6s  
版本:10.3.1
微信版本:6.5.7
蓝牙:4.2

手机名称:红米note
安卓版本:Android  4.4.4
微信版本:6.5.7
蓝牙:4.0

手机名称:小米mix
安卓版本:Android 6.0.1
微信版本:6.5.7
蓝牙:4.2

首先说下流程:
openBluetoothAdapter(初始化蓝牙适配器)—》 wx.startBluetoothDevicesDiscovery(开始搜寻附近的蓝牙外围设备)——》wx.getBluetoothDevices(获取所有已发现的蓝牙设备)——》wx.createBLEConnection(连接设备)——》wx.getBLEDeviceServices(获取蓝牙设备所有 service(服务))——》wx.getBLEDeviceCharacteristics(获取notify 特征值)——》wx.notifyBLECharacteristicValueChange(开启notify)——》 wx.onBLECharacteristicValueChange(监听低功耗蓝牙设备的特征值变化)——》wx.getBLEDeviceCharacteristics(获取write特征 )——》wx.writeBLECharacteristicValue(发送 数据到设备中)

整个流程就这样,因为开启了onBLECharacteristicValueChange,所以你在写入数据(writeBLECharacteristicValue)的时候,设备应答的数据就被监测到了,也就是说,最终最终获取的数据是在wx.onBLECharacteristicValueChange这个接口中的。
我们来看看官方的例子:

// 向蓝牙设备发送一个0x00的16进制数据
let buffer = new ArrayBuffer(1)
let dataView = new DataView(buffer)
dataView.setUint8(0, 0)

wx.writeBLECharacteristicValue({
 // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: deviceId,
 // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: serviceId,
 // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
characteristicId: characteristicId,
 // 这里的value是ArrayBuffer类型
value: buffer,
 success: function (res) {
   console.log(‘writeBLECharacteristicValue success’, res.errMsg)
 }
})
这里得解释一下ArrayBuffer:ArrayBuffer对象不提供任何直接读写内存的方法,只允许在其上方建立视图,然后通过视图读写(来自http://blog.csdn.net/lichwei1983/article/details/43893025)
但是我们传的值是buffer,当你console.log(buffer)的时候,出来的是一个空对象就对了,因为上面那句话已经解释了:不提供任何直接读写内存的方法。其实数据已经写到buffer中的了,只是console.log(buffer)不能直接打印出来而已(空对象)。在我们的小程序中,通过writeBLECharacteristicValue其实已经把数据包发送出去了,回调也是success,那我们就可以大胆地在notifyBLECharacteristicValueChange的监听事件中拿value了(前提是你写入蓝牙服务通道以及指令是正确的),只不过需要多做一件事情,借助Dataview才能把数据拿出来,跟写入也是一样的(直接打印characteristic也是空的):

 wx.notifyBLECharacteristicValueChange({        deviceId: that.data.deviceId,  //设备mac   IOS和安卓系统不一样        serviceId: that.data.notifyServiceId,     //服务通道,这里主要是notify        characteristicId: that.data.cd01,     //notify uuid        state: true,        success: function (res) {            console.log("开启notify 成功")            //TODO  onBLECharacteristicValueChange  监听特征值 设备的数据在这里获取到                wx.onBLECharacteristicValueChange(function (characteristic) {                    console.log('characteristic value comed:')                    let buffer = characteristic.value                    let dataView = new DataView(buffer)                    let dataResult = []                    console.log("拿到的数据")                    console.log("dataView.byteLength", dataView.byteLength)                    for (let i = 0; i  dataView.byteLength; i++) {                        console.log("0x" + dataView.getUint8(i).toString(16))                        dataResult.push(dataView.getUint8(i).toString(16))                    }                    const result = dataResult                })        },        fail: function (res) {}    })

IOS确实可以很顺利拿到data,但是对于我们的安卓系统呢?里面有一个坑,我自己掉坑里很久都出不来,直到一个同事的指导:

  bindViewTap: function () {        var that = this;        let buffer = new ArrayBuffer(5)        let dataView = new DataView(buffer)        //写入通道指令         dataView.setUint8(0, 0x1B)    //这里也能写十进制数        dataView.setUint8(1, 0x11)    //...        dataView.setUint8(2, 0x03)        dataView.setUint8(3, 0x00)        dataView.setUint8(4, 0x00)        console.log("发送的数据:")        for (let i = 0; i  dataView.byteLength; i++) {            console.log("0x" + dataView.getUint8(i).toString(16))        }        wx.writeBLECharacteristicValue({            deviceId: that.data.deviceId,            serviceId: that.data.writeServiceId,            characteristicId: that.data.cd20,    //write            value: buffer,            success: function (res) {                console.log("success  指令发送成功");            },            fail: function (res) {                // fail                console.log(res);            }        })    /**     * 坑就在这里了,对于安卓系统,需要添加下面这段代码。你写完数据后,还必须读一次,才能被onBLECharacteristicValueChange监听到,才会把数据返回给你,     * 但在苹果系统里面就不能有下面这段代码了,因为如果你添加上去的话,会出现发一次指令出现两次返回值的情况     */        wx.readBLECharacteristicValue({            deviceId: that.data.deviceId,            serviceId: that.data.notifyServiceId,            characteristicId: that.data.cd01,            success: function (res) {                console.log('readBLECharacteristicValue')            }        })    }})

但这里还得说一下,测试结果是API对IOS系统支持良好。但对于安卓系统,低版本(蓝牙4.0以上,系统4.x.x)的情况是,虽然能拿到数据,但是有时候不知道是手机太老的问题还是API不稳定的问题,拿到的数据有时候不全。然而对于6.x.x的安卓系统(蓝牙也是4.x以上)则是完全拿不到数据,这个很奇怪,原因尚不清楚,好大个坑啊,也欢迎各位解答一下

不足之处,请各位朋友指正

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎