项目需要使用小程序的蓝牙功能与硬件设备进行连接相互传送数据指令 ,首先说下流程:
openBluetoothAdapter(初始化蓝牙适配器)—》 wx.startBluetoothDevicesDiscovery(开始搜寻附近的蓝牙外围设备)——》wx.getBluetoothDevices(获取所有已发现的蓝牙设备)——》wx.createBLEConnection(连接设备)——》wx.getBLEDeviceServices(获取蓝牙设备所有 service(服务))——》wx.getBLEDeviceCharacteristics(获取notify 特征值)——》wx.notifyBLECharacteristicValueChange(开启notify)——》 wx.onBLECharacteristicValueChange(监听低功耗蓝牙设备的特征值变化)——》wx.getBLEDeviceCharacteristics(获取write特征 )——》wx.writeBLECharacteristicValue(发送 数据到设备中)
我们来看看官方的例子:
// 向蓝牙设备发送一个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对象不提供任何直接读写内存的方法,只允许在其上方建立视图,然后通过视图读写, 但是我们传的值是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以上)则是完全拿不到数据,这个很奇怪,原因尚不清楚
运动中听着美美的音乐自然让人心旷神怡,腿也更有劲了!当然,既不想尴尬,又想有更好的运动时听歌体验,最佳方式莫过于戴上一款蓝牙运动耳机!
目前小程序生态越来越丰富,微信给予了小程序一定的硬件通信能力这是之前 Web 很少尝试的事情。关于蓝牙,常见的就下面几个 API:
在现代生活方式中,蓝牙技术的应用已经非常普及,这是一种短距离通信开放标准,利用嵌入式芯片实现较短距离之间的无线连接,具有低成本、低功耗、模块体积小、易于集成等特点,非常适合在新型物联网移动设备中应用
微信小程序中很早就支持了蓝牙能力,看过不少的文档,知道大概的流程和能实现的效果,但是由于一直没有像样的实战项目导致也没有正经的开发上线过,本次缘于接到了一个外包项目
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!