前言:UNI-APP是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。即使你不需要发布到那么多的平台,UNI-APP也是一个不错的微信小程序的开发框架
UNI-APP的官网
了解蓝牙API返回的报错
错误码 | 错误信息 | 说明 |
---|---|---|
0 | ok | 正常 |
10000 | not init | 未初始化蓝牙适配器 |
10001 | not available | 当前蓝牙适配器不可用 |
10002 | no device | 没有找到指定设备 |
10003 | connection fail | 连接失败 |
10004 | no service | 没有找到指定服务 |
10005 | no characteristic | 没有找到指定特征值 |
10006 | no connection | 当前连接已断开 |
10007 | property not support | 当前特征值不支持此操作 |
10008 | system error | 其余所有系统上报的异常 |
10009 | system not support | Android 系统特有,系统版本低于 4.3 不支持 BLE |
10012 | operate time out | 连接超时 |
10013 | invalid_data | 连接 deviceId 为空或者是格式不正确 |
初始化蓝牙模块
uni.openBluetoothAdapter(OBJECT)
- 其他蓝牙相关 API 必须在这个方法调用之后使用。否则 API 会返回错误(errCode=10000)。
- 在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,调用这个方法会返回错误(errCode=10001),表示手机蓝牙功能不可用。
- 初始化完成后,可通过
uni.onBluetoothAdapterStateChange
监听手机蓝牙状态的改变,也可以调用蓝牙模块的所有API。
示例代码
uni.openBluetoothAdapter({
success: (res) => {
if (res.errMsg == 'openBluetoothAdapter:ok') {}
}
})
监听蓝牙状态变化事件
uni.onBluetoothAdapterStateChange(CALLBACK)
CALLBACK 返回参数
属性 | 类型 | 说明 |
---|---|---|
available | boolean | 蓝牙适配器是否可用 |
discovering | boolean | 蓝牙适配器是否处于搜索状态 |
示例代码
uni.onBLEConnectionStateChange((res) => {
if (res.connected == false) {
this.cut = true
uni.showModal({
title: "蓝牙连接断开",
content: "是否重新搜索",
success: (res) => {
if (res.confirm) this.search()
}
})
}
})
搜索周围的蓝牙
uni.startBluetoothDevicesDiscovery(OBJECT)
- App 端目前仅支持发现ble蓝牙设备
- 开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用
uni.stopBluetoothDevicesDiscovery
方法停止搜索。
OBJECT 参数说明
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
services | Array | 否 | 要搜索但蓝牙设备主 service 的 uuid 列表。某些蓝牙设备会广播自己的主 service 的 uuid。如果设置此参数,则只搜索广播包有对应 uuid 的主服务的蓝牙设备。建议主要通过该参数过滤掉周边不需要处理的其他蓝牙设备。 | |
allowDuplicatesKey | boolean | false | 否 | 是否允许重复上报同一设备。如果允许重复上报,则 uni.onBlueToothDeviceFound 方法会多次上报同一设备,但是 RSSI 值会有不同。 |
interval | number | 0 | 否 | 上报设备的间隔。0 表示找到新设备立即上报,其他数值根据传入的间隔上报。 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true, //是否允许重复上报同一设备
interval: 0, //搜索间隔
success: (res2) => {
if (res2.errMsg == 'startBluetoothDevicesDiscovery:ok') {
this.monitor()
}
}
})
监听寻找到新设备的事件
uni.onBluetoothDeviceFound(CALLBACK)
CALLBACK 返回参数
属性 | 类型 | 说明 |
---|---|---|
devices | Array | 新搜索到的设备列表 |
devices 的结构
属性 | 类型 | 说明 |
---|---|---|
name | string | 蓝牙设备名称,某些设备可能没有 |
deviceId | string | 用于区分设备的 id |
RSSI | number | 当前蓝牙设备的信号强度 |
advertisData | ArrayBuffer | 当前蓝牙设备的广播数据段中的 ManufacturerData 数据段 |
advertisServiceUUIDs | Array | 当前蓝牙设备的广播数据段中的 ServiceUUIDs 数据段 |
localName | string | 当前蓝牙设备的广播数据段中的 LocalName 数据段 |
serviceData | Object | 当前蓝牙设备的广播数据段中的 ServiceData 数据段 |
- 若在
uni.onBluetoothDeviceFound
回调了某个设备,则此设备会添加到uni.getBluetoothDevices
(有兴趣的话的查找一下)接口获取到的数组中。
示例代码
uni.onBluetoothDeviceFound((res) => {
res.devices.forEach(result => {
if ((result.name != '') && (result.localName != '')) {
let idx = util.inArray(this.booth.list, 'deviceId', result.deviceId)
if (idx === -1) {
this.booth.list.push(result)
} else {
this.booth.list[idx] = result
}
}
})
})
停止搜寻附近的蓝牙外围设备
uni.stopBluetoothDevicesDiscovery(OBJECT)
- 搜索蓝牙是很费资源的行为,若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
OBJECT 参数说明
属性 | 类型 | 说明 |
---|---|---|
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码
stopSearch() {
uni.stopBluetoothDevicesDiscovery()
}
连接低功耗蓝牙设备
uni.createBLEConnection(OBJECT)
- 若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。
- 蓝牙连接随时可能断开,建议监听
uni.onBLEConnectionStateChange
回调事件,当蓝牙设备断开时按需执行重连操作 - 若对未连接的设备或已断开连接的设备调用数据读写操作的接口,会返回 10006 错误,建议进行重连操作。
- 尽量成对的调用连接和断开的接口,如果多次调用连接接口,有可能导致系统持有同一设备多个连接的实例,导致调用断开接口失效
OBJECT 参数说明
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
deviceId | string | 是 | 用于区分设备的 id |
timeout | number | 否 | 超时时间,单位ms,不填表示不会超时 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码
uni.createBLEConnection({
deviceId: this.uuid.deviceId,
success: (res) => {
if (res.errMsg == 'createBLEConnection:ok') {
setTimeout(() => {
this.Service()
this.BLEChange()
}, 2000)
}
}
})
获取蓝牙设备所有服务
uni.getBLEDeviceServices(OBJECT)
- 这里有一个坑,连接设备成功后,不能立即调用
uni.getBLEDeviceServices(OBJECT)
,否则获取不到任何服务。解决方法:连接成功后,等个几秒(看设备的情况)在调用uni.getBLEDeviceServices(OBJECT)
OBJECT 参数说明
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
deviceId | string | 是 | 蓝牙设备 id |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
属性 | 类型 | 说明 |
---|---|---|
services | Array | 设备服务列表 |
res.services 的结构
属性 | 类型 | 说明 |
---|---|---|
uuid | string | 蓝牙设备服务的 uuid |
isPrimary | boolean | 该服务是否为主服务 |
示例代码
uni.getBLEDeviceServices({
deviceId: this.uuid.deviceId,
success: (res) => {
if (res.services.length == 0) {
util.showError("找不到服务")
} else {
let booth = true
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].uuid == this.uuid.service) {
booth = false
this.Character()
break;
}
}
if (booth) util.showError("服务uuid错误")
}
}
})
获取蓝牙设备某个服务中所有特征值
uni.getBLEDeviceCharacteristics(OBJECT)
OBJECT 参数说明
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
deviceId | string | 是 | 蓝牙设备 id |
serviceId | string | 是 | 蓝牙服务 uuid,需要使用getBLEDeviceServices 获取 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
属性 | 类型 | 说明 |
---|---|---|
characteristics | Array | 设备服务列表 |
res.characteristics 的结构
属性 | 类型 | 说明 |
---|---|---|
uuid | string | 蓝牙设备特征值的 uuid |
properties | Object | 该特征值支持的操作类型 |
properties 的结构
属性 | 类型 | 说明 |
---|---|---|
uuid | string | 蓝牙设备特征值的 uuid |
read | boolean | 该特征值是否支持 read 操作 |
write | boolean | 该特征值是否支持 write 操作 |
notify | boolean | 该特征值是否支持 notify操作 |
indicate | boolean | 该特征值是否支持 indicate操作 |
- read:读取操作
- write:写入操作
示例代码
uni.getBLEDeviceServices({
deviceId: this.uuid.deviceId,
success: (res) => {
if (res.services.length == 0) {
util.showError("找不到服务")
} else {
let booth = true
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].uuid == this.uuid.service) {
booth = false
this.Character()
break;
}
}
if (booth) util.showError("服务uuid错误")
}
}
})
启用低功耗蓝牙设备特征值变化时的 notify 功能
uni.notifyBLECharacteristicValueChange(OBJECT)
- 必须设备的特征值支持 notify 或者 indicate 才可以成功调用
- 订阅操作成功后需要设备主动更新特征值的 value,才会触发
uni.onBLECharacteristicValueChange
(后续监听设备的返回消息)回调 - 安卓平台上,在调用
notifyBLECharacteristicValueChange
成功后立即调用```writeBLECharacteristicValue``(向设备发送信息)接口,在部分机型上会发生 10008 系统错误 - 自此,连接蓝牙设备的过程
OBJECT 参数说明
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
deviceId | string | 是 | 蓝牙设备 id |
serviceId | string | 是 | 蓝牙特征值对应服务的 uuid |
characteristicId | string | 是 | 蓝牙特征值的 uuid |
state | boolean | 是 | 是否启用 notify |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码
uni.notifyBLECharacteristicValueChange({
deviceId: this.uuid.deviceId,
serviceId: this.uuid.service,
characteristicId: this.uuid.character,
state: true,
success: (res) => {
if (res.errMsg == 'notifyBLECharacteristicValueChange:ok') {
uni.hideLoading();
this.cut = false
this.BLEValue()
}
}
})
监听低功耗蓝牙设备的特征值变化事件(获取设备发送的信息)
uni.onBLECharacteristicValueChange(CALLBACK)
- 监听低功耗蓝牙设备的特征值变化事件。必须先启用
notifyBLECharacteristicValueChange
接口才能接收到设备推送的 notification。 - 有些蓝牙设备发送的信息是多段发送的,需要特殊处理
CALLBACK 返回参数
属性 | 类型 | 说明 |
---|---|---|
deviceId | string | 蓝牙设备 id |
serviceId | string | 蓝牙特征值对应服务的 uuid |
characteristicId | string | 蓝牙特征值的 uuid |
value | ArrayBuffer | 特征值最新的值 |
- 接收设备发送过来的信息,需要对value字段进行处理才能获取到信息
- 汉字的编码格式也需要进行特殊处理
###示例代码
uni.onBLECharacteristicValueChange((res) => {
let caseoff = this.operation.Receive + util.ab2Str(res.value)
let len = caseoff.length - 1
let i = caseoff.charCodeAt(len)
if (i < 127) {
this.operation.Receive = ""
caseoff = util.gbkStrToUtf16Str(caseoff)
this.operation.receive += caseoff
} else {
if (caseoff.charCodeAt(len - 1) > 127) {
this.operation.Receive = ""
caseoff = util.gbkStrToUtf16Str(caseoff)
this.operation.receive += caseoff
} else {
this.operation.Receive = caseoff
}
}
})
向低功耗蓝牙写入数据
uni.writeBLECharacteristicValue(OBJECT)
- 必须设备的特征值支持 write 才可以成功调用。
- 并行调用多次会存在写失败的可能性。
- APP不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
- 若单次写入数据过长,iOS 上存在系统不会有任何回调的情况(包括错误回调)。
- 安卓平台上,在调用
notifyBLECharacteristicValueChange
成功后立即调用writeBLECharacteristicValue
接口,在部分机型上会发生 10008 系统错误
OBJECT 参数说明
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
deviceId | string | 是 | 蓝牙设备 id |
serviceId | string | 是 | 蓝牙特征值对应服务的 uuid |
characteristicId | string | 是 | 蓝牙特征值的 uuid |
value | ArrayBuffer | 是 | 蓝牙设备特征值对应的二进制值 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码
let j = 0;
for (let i = 0; i < SendStr.length / 20; i++) {
setTimeout(() => {
let setData = SendStr.substring(j, j + 20)
setData = new Uint8Array(util.stringToBytes(setData)).buffer
j = j + 20
uni.writeBLECharacteristicValue({
deviceId: this.uuid.deviceId,
serviceId: this.uuid.service,
characteristicId: this.uuid.write,
value: setData,
fail: (err) => {
util.showError("发生错误")
}
})
}, i * 300)
}
以上就是UNI-APP连接蓝牙设备的内容了,如有不理解的地方或者需要码源的小伙可以联系我。