最近业务上有这个场景,项目完毕后,简单记录下。
一、前置核心API:
相关文档:developers.weixin.qq.com/miniprogram…
搜索蓝牙:
- openBluetoothAdapter // 开启蓝牙适配器
- onBluetoothAdapterStateChange // 监听蓝牙适配器状态
- onBluetoothDeviceFound // 监听寻找蓝牙设备 (部分安卓需要位置权限)
- startBluetoothDevicesDiscovery //开启蓝牙搜索功能
- getBluetoothDevices // 获取已发现的蓝牙设备,包括已经和本机的链接状态的设备
连接蓝牙
- createBLEConnection //连接蓝牙
- getBLEDeviceServices //获取蓝牙服务
- getBLEDeviceCharacteristics //获取蓝牙设备特征值
- notifyBLECharacteristicValueChange // 开启蓝牙设备订阅
- writeBLECharacteristicValue // 向设备写入
- onBLECharacteristicValueChange// 监听蓝牙设备值的变化
二、流程图:
1、获取蓝牙:
2、连接蓝牙
三、核心代码:
1、开启并搜索蓝牙
//开启蓝牙
const handleBluetoothAdapter = () => {
Taro.openBluetoothAdapter({
success(res) {
// 监听寻找设备事件
onBluetoothDeviceFound()
// 开启需按照蓝牙设备
startBluetoothDevicesDiscovery()
},
fail(error) {
//监听本机蓝牙状态变化的事件
onBluetoothAdapterStateChange()
if (error.errCode === 10001) {
//没有蓝牙权限给出提示
}
}
})
}
//监听本机蓝牙状态变化的事件
const onBluetoothAdapterStateChange = () => {
Taro.onBluetoothAdapterStateChange(function (res) {
const available = res.available
if (available) {
//重新开蓝牙
handleBluetoothAdapter()
}
})
}
// 开启蓝牙搜索功能
const startBluetoothDevicesDiscovery = () => {
Taro.startBluetoothDevicesDiscovery({
// 固定蓝牙UUID
services: [XXX]
success() {
console.log("打开蓝牙搜索功能成功")
},
fail(e) {
console.log("打开蓝牙搜索功能失败", e)
}
})
}
//监听寻找到新设备的事件
const onBluetoothDeviceFound = () => {
Taro.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
// 存储获取到的蓝牙设备End
})
})
}
2、连接蓝牙
// 开始链接蓝牙
const createBLEConnection = () => {
Taro.createBLEConnection({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: XXX, //设备ID
success: function (res) {
// 进入链接设备的状态
getBLEDeviceServices()
}
})
}
// 获取蓝牙服务
const getBLEDeviceServices = () => {
Taro.getBLEDeviceServices({
deviceId:XXX //设备ID
success(res) {
getBLEDeviceCharacteristics() //获取特征值
setTimeout(() => {
notifyBLECharacteristicValueChange() // 开启订阅
writeBLECharacteristicValue() //写入
}, 1500)
},
fail(res) {
console.log('device services:', res)
}
})
}
//获取特征值
const getBLEDeviceCharacteristics = () => {
Taro.getBLEDeviceCharacteristics({
deviceId: XXX, //设备ID
serviceId: XXX, // 服务ID
success(res) {
// 获取特征值 res.characteristics
}
})
}
// 开启订阅值
const notifyBLECharacteristicValueChange = () => {
// 取可以notify的特征值
Taro.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: XXX, //设备ID
serviceId: XXX,// 服务ID
characteristicId: XXX,//特征值ID
success(res: any) {
// 监听设备特征值变化
getonBLECharacteristicValueChange()
}
})
}
//监听设备特征值变化
const getonBLECharacteristicValueChange = () => {
Taro.onBLECharacteristicValueChange((onNotityChangeRes) => {
// 处理蓝牙返回值
})
}
// 向设备写入值
const writeBLECharacteristicValue = () => {
// 取可以write的特征值
Taro.writeBLECharacteristicValue({
deviceId: XXX, //设备ID
serviceId: XXX,// 服务ID
characteristicId: XXX,//特征值ID
// 这里的value是ArrayBuffer类型
value: XXX,
success(res) {
console.log('写入成功' +res)
},
fail(res) {
console.log("写入数据失败" + res);
}
});
}
四、注意事项:
- 流程完毕后,要及时 closeBluetoothAdapter。
实际场景:整体流程完毕后,onBluetoothDeviceFound 无法再监听到设备信息,重定向页面,重置监听onBluetoothDeviceFound 也无效。
-
writeBLECharacteristicValue,notifyBLECharacteristicValueChange 两个API的入参中,
characteristicId 是根据getBLEDeviceCharacteristics 获取的,但是一般会获取到多个Id。区别如下:
notifyBLECharacteristicValueChange:notify:true
writeBLECharacteristicValue:write:true
-
获取特征值,开启订阅,写入设备信息,这几流程,建议加一些异步延迟,保证流程畅通。
-
onBluetoothDeviceFound 文档表明,部分安卓机需要位置权限,才可。具体设备未知。