uni-app上面封装的蓝牙功能api源于HTML5+所封装的,虽然uniapp莫名其妙进行了蓝牙和低功耗蓝牙的划分,但依旧和H5+上的能进行严格对应,如下图(不用细看);因此,若因为框架问题无法使用uniapp上的api,可放心使用H5+;
下面将以蓝牙功能开发时间线整理这些api的调用;
第一步,初始界面进行【初始化蓝牙】【提示用户连接情况】
初始化蓝牙板块
【初始化蓝牙-onLoad】页面初始化时直接调用;
openBluetoothAdapter() {
return new Promise((resolve, reject) => {
uni.openBluetoothAdapter({
success(res) {
resolve(res)
},
fail(res) {
console.log('蓝牙模块初始化失败', res)
reject(res)
}
})
})
},
获取本机蓝牙适配器状态
【提示用户连接情况-onLoad/onShow】监听蓝牙板块开启情况和搜索情况(蓝牙功能未开启时,提示用户)这里用H5+只是告诉大家可以不仅仅用uniapp的api,其实和uniapp的uni.getBluetoothAdapterState(OBJECT)一样;
onBluetoothAdapterStateChange() {
return new Promise((resolve, reject) => {
plus.bluetooth.getBluetoothAdapterState({
success: (e) => {
console.log('蓝牙设备情况', e)
resolve(e)
},
fail: (e) => {
uni.showToast({
title: '蓝牙功能异常',
icon: "error",
duration: 1500
})
console.log('蓝牙设备异常', e)
reject(e)
}
});
})
},
第二步,蓝牙连接页面进行【设备搜索】【新设备捕获】【关闭搜索】【设备连接】【设备断开】
开始搜寻附近的蓝牙外围设备
【设备搜索-按钮启动】services参数可以有效过滤无关的蓝牙设备。所需的uuid需要参考蓝牙设备厂商提供的蓝牙协议;
uni.startBluetoothDevicesDiscovery({
services: this.advertisServiceUUIDs,
success(res) {
console.log('开始搜索设备', res)
}
})
监听寻找到新设备的事件
【新设备捕获-界面渲染】将搜索到的设备渲染到界面上,比如有BLEList这个数组通过for循环在页面渲染了新设备列表;
uni.onBluetoothDeviceFound((res) => {
let new = res.devices[0]
console.log('发现了新设备【无过滤】', res)
// this.BLEList.push(res)
if (new.advertisServiceUUIDs = this.advertisServiceUUIDs && new.localName) {
//安卓需要加条件 要不然搜出很多奇怪设备
this.BLEList.push(new)
console.log('发现了新设备【uuid过滤】', res)
}
})
停止搜寻附近的蓝牙外围设备
【关闭搜索-计时器或搜索成功调用】因为开启蓝牙搜索极其消耗性能,因此在不需要搜索后需要关闭。其条件可以是【计时器】或搜索到【目标设备】;
//【计时器】15s后没有搜索到设备 就关闭蓝牙搜索 并通知用户
setTimeout(() => {
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log('关闭蓝牙搜索', res)
//通知用户,搜索停止,如:关闭搜索动画,或弹窗提示
}
})
}, 15000)
//【目标设备】搜索到目标设备后关闭搜索
uni.onBluetoothDeviceFound((res) => {
let new = res.devices[0]
if (new.advertisServiceUUIDs = this.advertisServiceUUIDs ) {
this.BLEList.push(new)
console.log('发现了目标设备【条件过滤】', res)
uni.stopBluetoothDevicesDiscovery({
success(res) {
console.log('关闭蓝牙搜索', res)
}
})
}
})
连接低功耗蓝牙设备
【设备连接-按钮点击】建议加上链接动效,以及成功与失败提醒;
createBLEConnection(deviceId) {
return new Promise((resolve, reject) => {
uni.createBLEConnection({
deviceId,
succes(res) {
console.log("连接设备成功!", res)
uni.showToast({
title: '连接成功',
duration: 1500
})
resolve(res)
},
fail(res) {
uni.showToast({
title: '连接失败',
icon: "error",
duration: 2000
})
console.log("连接设备失败!", res)
reject(res)
}
})
})
},
断开与低功耗蓝牙设备的连接
【设备断开-按钮点击】
closeBLEConnection(deviceId){
uni.closeBLEConnection({
deviceId,
success(res) {
console.log('断开成功',res)
//写入断开连接操作,比如弹窗提醒,页面跳转
uni.showToast({
title: '断开设备成功',
duration: 2000
})
}
})
},
第三步,设备数据交互页面进行【数据监听】【数据写入】
监听低功耗蓝牙设备的特征值变化事件
【数据监听-onShow】 注意:
- 开启监听特征值,写在onShow 这样在设置页连接设备后 再打开数据交互页面就可以正常开启,不能写在onload;
- 必须先启用
notifyBLECharacteristicValueChange接口才能接收到设备推送的 notification; - 接收到的数据是ArrayBuffer类型,一般是转16进度字符串;
- serviceId与characteristicId需要对应接口获取
openNotify() {
uni.onBLECharacteristicValueChange(async (res) => {
let value = this.ab2hex(res.value)
console.log('接受到的数据是:', value)
//这里书写获取到的16进制数据的处理,注意大小端颠倒
uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: this.deviceId,
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
serviceId: "696530001-0405-0607-0809-0A0B0C0D0E0F",
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
characteristicId: "69650002-0405-0607-0809-0A0B0C0D0E0F",
success(res) {
console.log('设备notify已开启', res)
},
fail(res) {
console.log('notify开启失败', res)
}
})
},
//buffer转hex类型(设备返还数据转0x开头的16进制字符串)
ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
},
向低功耗蓝牙设备特征值中写入二进制数据
【数据写入】H5+和uni-app的API参数上,uni-app需要多一个writeType参数;
//写入调用 this.write(this.string2buffer(value))
write(value) {
let that = this
new Promise((resolve, reject) => {
plus.bluetooth.writeBLECharacteristicValue({
deviceId: that.deviceId,
serviceId: "69650001-0405-0607-0809-0A0B0C0D0E0F",
characteristicId: "69650003-0405-0607-0809-0A0B0C0D0E0F",
value,
success: function(e) {
console.log('写入数据 success: ' + JSON.stringify(e));
resolve(e)
},
fail: function(e) {
console.log('写入数据 failed: ' + JSON.stringify(e));
reject(e)
});
})
},
//字符串转buffer
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
},
以上就是蓝牙功能整体开发所需要的各项主要api与其代码,若有疑惑的地方欢迎评论探讨!!!