转载自微信小程序-蓝牙配网功能
使用蓝牙功能去连接一个蓝牙设备,我们需要知道这个设备的名称,这个设备名称我是通过扫码得到的,得到这个设备的详细信息以后,我们就需要初始化蓝牙模块
1.0 初始化蓝牙模块
startBleAdapter() {
var that = this
wx.openBluetoothAdapter({
success: function (res) {
that.getBluetoothAdapterState()
},
fail: function (res) {
if (res.errCode == 10001) {
//手机蓝牙不可用
console.log('手机蓝牙不可用: ' + res)
wx.showToast({
title: '手机蓝牙不可用,请开启蓝牙再试~',
icon: 'none',
duration: 2000
})
} else if (res.errCode == 103 || res.errno == 103) {
//授权问题
that.openConfirm()
}
}
})
},
// 再次获取授权,引导客户手动授权
openConfirm() {
wx.showModal({
content: '检测到您没打开此小程序的蓝牙权限,是否去设置打开?',
confirmText: "确认",
cancelText: "取消",
success: (res) => {
//点击“确认”时打开设置页面
if (res.confirm) {
wx.openSetting({
success: (res) => {}
})
} else {
console.log('用户点击取消')
}
}
})
}
在初始化蓝牙模块的时候我遇到了第一个问题,可谓出师不利,在我初始化手机上蓝牙模块的时候,wx.openBluetoothAdapter这个api一直调用失败,说我手机没有打开蓝牙,可是我检查了好几遍,手机上的蓝牙我是开启了的,代码也没啥问题,手动狗头。最后面向百度编程,才得知,当你使用苹果手机的时候(安卓的没试过),光打开设置了里面的蓝牙是不够的,还得将设置–>微信–>蓝牙打开才OK
2.0 获取本机蓝牙适配器状态
//检测本机蓝牙是否可用
getBluetoothAdapterState() {
var that = this
//获取本机蓝牙适配器状态
wx.getBluetoothAdapterState({
success: function (res) {
if (res.errMsg == 'getBluetoothAdapterState:ok') {
//搜寻附近的蓝牙设备
that.startBluetoothDevicesDiscovery()
}
//{errMsg: "getBluetoothAdapterState:ok", available: true, discovering: false}
},
fail: function (res) {
// console.log('获取本机蓝牙适配器状态', res)
},
})
},
3.0 获取本机蓝牙适配器状态
getBluetoothAdapterState() {
var that = this
//获取本机蓝牙适配器状态
wx.getBluetoothAdapterState({
success: function (res) {
if (res.errMsg == 'getBluetoothAdapterState:ok') {
//搜寻附近的蓝牙设备
that.startBluetoothDevicesDiscovery()
}
},
fail: function (res) {
console.log('获取本机蓝牙适配器状态', res)
},
})
},
4.0 开始搜寻附近的蓝牙外围设备
startBluetoothDevicesDiscovery() {
var that = this;
console.log('开始搜寻附近的蓝牙外围设备')
wx.startBluetoothDevicesDiscovery({
powerLevel: "high",
success: function (res) {
console.log('开始搜寻附近的蓝牙外围设备: ', res)
if (res.errCode == 0) {
// 监听寻找到新设备的事件
that.onBluetoothDeviceFound()
}
},
fail: function (res) {
console.log('开始搜寻附近的蓝牙外围设备,发生错误: ', res)
}
})
},
5.0 监听寻找到新设备的事件
onBluetoothDeviceFound() {
var that = this
wx.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
const foundDevices = that.data.devices
const idx = that.inArray(foundDevices, 'deviceId', device.deviceId)
console.log(idx);
const data = {}
if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device
} else {
data[`devices[${idx}]`] = device
}
that.setData(data)
})
})
},
6.0 连接蓝牙
createBLEConnection(e) {
var that = this
const ds = e.currentTarget.dataset
const deviceId = ds.deviceId
const name = ds.name
//连接蓝牙前先关闭已连接蓝牙
wx.createBLEConnection({
deviceId: deviceId,
success: function (res) {
console.log('连接蓝牙成功', res)
//获取连接设备的service服务
that.getBLEDeviceServices(deviceId);
//停止搜寻附近的蓝牙外围设备
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log('停止搜寻附近的蓝牙外围设备',res)
},
fail:function(res){
}
})
},
fail: function (res) {
console.log('连接蓝牙失败', res)
},
})
},
7.0 获取连接设备的service服务
getBLEDeviceServices(deviceId) {
var that = this
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function (res) {
console.log('获取连接设备的service服务', res)
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary && res.services[i].uuid == serviceUUID) {
that.setData({
deviceId: deviceId,
serviceId: res.services[i].uuid
})
//获取连接设备的所有特征值
that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
}
}
},
fail: function (res) {
console.log('获取蓝牙失败', res)
}
})
},
8.0 获取连接设备的所有特征值
getBLEDeviceCharacteristics(deviceId, serviceId) {
var that = this
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success: function (res) {
console.log('获取连接设备的所有特征值', res);
if (res.errCode == 0) {
that.setData({
lbeCharacteristics: res.characteristics
})
for (var i = 0; i < res.characteristics.length; i++) {
console.log("readCharcteristicUUID: ",readCharcteristicUUID)
if (that.data.lbeCharacteristics[i]['properties']['read'] && that.data.lbeCharacteristics[i]['uuid'] === readCharcteristicUUID) {
that.setData({
deviceReadCharcteristicUUID: that.data.lbeCharacteristics[i]['uuid']
})
} else if (that.data.lbeCharacteristics[i]['properties']['write'] && that.data.lbeCharacteristics[i]['uuid'] === writeCharcteristicUUID) {
that.setData({
deviceWriteCharcteristicUUID: that.data.lbeCharacteristics[i]['uuid']
})
}
that.notifyBLECharacteristicValueChange(deviceId, serviceId, that.data.lbeCharacteristics[i]['uuid'])
}
//这里就可以去给蓝牙设备发送数据了
} else {
console.log('获取特征值失败')
}
},
})
},
9.0 启用低功耗蓝牙设备特征值变化时的 notify 功能
notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
var that = this
wx.notifyBLECharacteristicValueChange({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
state: true,
success: function (res) {
console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能', res)
that.onBLECharacteristicValueChange()
},
fail: function (res) {
console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能失败', res)
}
})
},
10.0 监听低功耗蓝牙设备的特征值变化事件(必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification)。此方法是接收蓝牙设备返回数据的
onBLECharacteristicValueChange() {
var that = this
wx.onBLECharacteristicValueChange(function (res) {
console.log('监听低功耗蓝牙设备的特征值变化事件: ', res)
console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
that.handleDeviceBleData(res.value)
})
},
BLE 4.0 中发送一个数据包只能包含 20 字节的数据,大于 20 字节只能分包发送。微信小程序提供的 API 中似乎没有自动分包的功能,这就只能自己手动分包了。调试中发现,在 iOS 系统中调用 wx.writeBLECharacteristicValue 发送数据包,回调 success 后紧接着发送下一个数据包,很少出现问题,可以很快全部发送完毕。而安卓系统中,发送一个数据包成功后紧接着发送下一个,很大概率会出现发送失败的情况,在中间稍做延时再发送下一个就可以解决这个问题(不同安卓手机的时间长短也不一致),照顾下一些比较奇葩的手机,大概需要延时 250 ms 。不太好的但是比较科学的办法是,只要成功发送一个数据包则发送下一个,否则不断重发,具体就是
wx.writeBLECharacteristicValue 回调 fail 则重新发送,直至发送完毕
下面这个链接是我一个前辈的博客,对我这个功能的开发帮组非常大,比我的更完善
www.cnblogs.com/guhonghao/p…