1.0 一般使用蓝牙功能肯定是想连接某一个蓝牙设备,所以需要知道这个蓝牙设备的名称,一般来说都是扫描二维码连接,那么当你扫描这个设备二维码的时候,就需要去初始化你手机上的蓝牙模块了
/**
* 初始化蓝牙设备
*/
initBlue:function(){
var that = this;
wx.openBluetoothAdapter({// 调用微信小程序 api 打开蓝牙适配器接口
success: function (res) {// console.log(res)
wx.showToast({
title: '初始化成功',
icon: 'success',
duration: 800
})
that.findBlue();//2.0},
fail: function (res) {// 如果手机上的蓝牙没有打开,可以提醒用户
wx.showToast({
title: '请开启蓝牙',
icon: 'fails',
duration: 1000
})
}
})
},
2.0 手机蓝牙初始化成功之后,就会去搜索周边的蓝牙设备
/**
* 开始搜索蓝牙设备
*/
findBlue(){
var that = this
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
interval: 0,
success: function (res) {
wx.showLoading({title: '正在搜索设备',})
that.getBlue()//3.0}
})
},
3.0 搜索蓝牙设备之后,需要获取搜索到的蓝牙设备信息,微信小程序提供了两个方法可以获取搜索到的蓝牙设备信息,分别是:
wx.onBluetoothDeviceFound(监听寻找到新设备的事件 ——表示只要找到一个新的蓝牙设备就会调用一次该方法)
wx.getBluetoothDevices(获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备)
看两个方法的介绍我们知道他们的区别,但是不了解他们的区别会造成什么样的问题?
第一次我使用的是 wx.onBluetoothDeviceFound 方法进行联调,发现一切正常,由于调试的时候就只有一台设备,发现第二次重新扫码这个蓝牙设备的时候,找不到这个设备了,因为对这个方法来说,这不是一个新的设备,以前连接上过;或者当你因为某些原因蓝牙传送数据指令的时候出错了需要重新连接,再次连接的时候也找不到当前设备,还是同样的原因,因为当前设备对这个方法来说不是一个新设备
所以后来我就用了 wx.getBluetoothDevices 方法
/**
* 获取搜索到的设备信息
*/
getBlue(){
var that = this
wx.getBluetoothDevices({success: function(res) {wx.hideLoading();
for (var i = 0; i < res.devices.length; i++){
//that.data.inputValue:表示的是需要连接的蓝牙设备 ID,简单点来说就是我想要连接这个蓝牙设备,所以我去遍历我搜索到的蓝牙设备中是否有这个 ID
if (res.devices[i].name == that.data.inputValue || res.devices[i].localName == that.data.inputValue){
that.setData({deviceId: res.devices[i].deviceId,
consoleLog: "设备:" + res.devices[i].deviceId,
})
that.connetBlue(res.devices[i].deviceId);//4.0
return;
}
}
},
fail: function(){console.log("搜索蓝牙设备失败")
}
})
},
4.0 通过 3.0 步骤找到这个蓝牙之后,通过蓝牙设备的 id 进行蓝牙连接
/**
* 获取到设备之后连接蓝牙设备
*/
connetBlue(deviceId){
var that = this;
wx.createBLEConnection({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: deviceId,// 设备 id
success: function (res) {
wx.showToast({
title: '连接成功',
icon: 'fails',
duration: 800
})
console.log("连接蓝牙成功!")
wx.stopBluetoothDevicesDiscovery({success: function (res) {console.log('连接蓝牙成功之后关闭蓝牙搜索');
}
})
that.getServiceId()//5.0}
})
},
5.0 连接上需要的蓝牙设备之后,获取这个蓝牙设备的服务 uuid
getServiceId(){
var that = this
wx.getBLEDeviceServices({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
success: function (res) {var model = res.services[0]
that.setData({services: model.uuid})
that.getCharacteId()//6.0}
})
},
6.0 如果一个蓝牙设备需要进行数据的写入以及数据传输,就必须具有某些特征值,所以通过上面步骤获取的 id 可以查看当前蓝牙设备的特征值
getCharacteId(){
var that = this
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.data.services,
success: function (res) {for (var i = 0; i < res.characteristics.length; i++) {// 2 个值
var model = res.characteristics[i]
if (model.properties.notify == true) {
that.setData({notifyId: model.uuid// 监听的值})
that.startNotice(model.uuid)//7.0
}
if (model.properties.write == true){
that.setData({writeId: model.uuid// 用来写入的值})
}
}
}
})
},
7.0
startNotice(uuid){
var that = this;
wx.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.data.services,
// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
characteristicId: uuid, // 第一步 开启监听 notityid 第二步发送指令 write
success: function (res) {
// 设备返回的方法
wx.onBLECharacteristicValueChange(function (res) {
// 此时可以拿到蓝牙设备返回来的数据是一个 ArrayBuffer 类型数据,所以需要通过一个方法转换成字符串
var nonceId = that.ab2hex(res.value)
// 拿到这个值后,肯定要去后台请求服务(当前步骤根据当前需求自己书写),获取下一步操作指令写入到蓝牙设备上去
wx.request({
method: "POST",
data: {xx:nonceId},
url: url,
success: (res) => {
//res.data.data.ciphertext:我这边服务返回来的是 16 进制的字符串,蓝牙设备是接收不到当前格式的数据的,需要转换成 ArrayBuffer
that.sendMy(that.string2buffer(res.data.data.ciphertext))//8.0
// 服务器返回一个命令 我们要把这个命令写入蓝牙设备
}
})
}
})
},
8.0 将从后台服务获取的指令写入到蓝牙设备当中
sendMy(buffer){
var that = this
wx.writeBLECharacteristicValue({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: that.data.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.data.services,
// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
characteristicId: that.data.writeId,// 第二步写入的特征值
// 这里的 value 是 ArrayBuffer 类型
value: buffer,
success: function (res) {console.log("写入成功")
},
fail: function () {console.log('写入失败')
},
complete:function(){console.log("调用结束");
}
})
},
//ps: 下面是需要使用到的两个格式相互转换的方法
/**
* 将字符串转换成 ArrayBufer
*/
string2buffer(str) {
let val = ""
if(!str) return;
let length = str.length;
let index = 0;
let array = []
while(index < length){array.push(str.substring(index,index+2));
index = index + 2;
}
val = array.join(",");
// 将 16 进制转化为 ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {return parseInt(h, 16)
})).buffer
},
/**
* 将 ArrayBuffer 转换成字符串
*/
ab2hex(buffer) {
var hexArr = Array.prototype.map.call(new Uint8Array(buffer),
function (bit) {return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
//PS:以上是蓝牙连接的全部流程,但是我们在实际使用中肯定不会这么顺畅,而且蓝牙发送指令的设备都会有一个特性,就是当前蓝牙设备有人连接上之后,其他人是搜索不到这个蓝牙设备的,所以你需要考虑在某些个特殊情况,代码里需要主动断开蓝牙连接把设备释放出来供其他用户使用,还有就是将指令写入蓝牙设备的时候很容易出问题,所以要写个回调去多次写入,保证成功性!第一次写博客,不正确的地方,欢迎大家讨论,谢谢!有些人会用小程序蓝牙功能去链接另外的手机蓝牙,但是发现搜索不到蓝牙信息,所以说明一下:微信小程序官方文档上说:只支持低功耗蓝牙设备,手机蓝牙是搜不到的
BLE 低功耗蓝牙具有以下要求的应用:
1. 通信距离长达 100 米左右。很多低功耗蓝牙需要使用纽扣电池运行。很多的物联网设备需要使用标准纽扣电池运行很多年。BLE 低功耗蓝牙可实现超低的峰值、均衡和空闲模式的功耗。另外,低占空比设备还能节省更多电能。
2. 多智能厂商互操作性。作为一个标准协议,BLE 低功耗蓝牙与此前的蓝牙版本一样,也得到了主设备制造商的广泛采用。也有很多的物联网从设备也支持 BLE 低功耗蓝牙。安卓、iOS、Windows 10、Linux 等主流操作系统均原生支持 BLE 低功耗蓝牙。预测,到 2020 年,95% 的智能手机都将支持 BLE 低功耗蓝牙。而这个生态系统将有助于实现多厂商互操作性。
3.BLE 低功耗蓝牙是搭建集体、家庭、个人网络的最佳选择,可通过无线方式将供电型智能设备连接至手机或计算机。因此,越来越多的智能穿戴设备、计算机 / 手机外设和医疗监测设备将 BLE 低功耗蓝牙视为了首选通信协议。在蓝牙技术联盟的网站上也列出了很多不同支持智能蓝牙协议的产品和蓝牙智能设备产品。这直接表明了 BLE 低功耗蓝牙通信协议在物联网应用领域的重要性。