HarmonyOS 鸿蒙Next物联网Iot开发-BLE设备扫描
HarmonyOS 鸿蒙Next物联网Iot开发-BLE设备扫描
<markdown _ngcontent-spp-c237="" class="markdownPreContainer">
前言
在鸿蒙系统(HarmonyOS)环境下,BLE(Bluetooth Low Energy)蓝牙设备扫描是一项核心功能,旨在帮助应用程序高效地探测周围低功耗蓝牙设备,为诸如智能穿戴、健康监控、智能家居等物联网设备的互连打下基础。
扫描机制概览
鸿蒙系统利用BLE 5.2技术标准,提供先进的扫描能力,确保在功耗控制与连接效率之间达到平衡。BLE扫描主要分为被动扫描和主动扫描两种模式。被动扫描是指设备监听周围的广播信息,不主动发起连接请求;而主动扫描则会在接收到广播的同时,向广播设备发送扫描请求,以获取更详尽的设备信息。这两种模式可根据应用需求灵活选择,通过配置扫描参数实现最优资源利用。
API与功能支持
鸿蒙系统的蓝牙API为开发者设计了一系列接口,以便轻松集成BLE设备扫描功能。核心API如startBLEScan
和stopBLEScan
分别用于启动和终止扫描过程。开发者可以通过ScanSettings
对象细致地配置扫描参数,比如设定扫描周期、模式、匹配过滤条件等,以优化扫描策略。同时,ScanFilter
功能允许针对特定设备特征(如服务UUID、设备名)进行筛选,从而精准定位目标设备。
事件响应与数据处理
一旦有设备被扫描发现,系统将触发BLEDeviceFind
事件,此时应用可获取设备的基本信息,包括设备名、MAC地址及信号强度(RSSI)等。此外,若扫描过程中遇到任何错误,如权限不足或硬件故障,通过事件捕获机制获取错误信息,便于开发者及时采取应对措施。
安全与权限管理
在确保用户体验和数据安全的前提下,鸿蒙系统对蓝牙权限管理严格要求。应用在执行扫描前必须获得相应的权限,例如ohos.permission.ACCESS_BLUETOOTH
,并且遵循系统指引处理用户许可,保障用户隐私。开发者应当在应用中合理请求权限,并在用户授权后方可执行蓝牙操作。
文档和实践指导
官方文档不仅提供了详尽的API说明,还包含丰富的示例代码,指导开发者如何从零开始配置蓝牙适配器、设定扫描参数、监听扫描事件直至成功识别BLE设备的全过程。这些实例代码极大地降低了开发难度,让开发者能迅速掌握BLE设备扫描的实践技巧。接下来,给大家分享下,BLE 蓝牙设备的封装过程。
文档地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-bluetooth-ble-V5
蓝牙扫描封装
配置权限
在工程的src/main/module.json5中配置蓝牙权限
"requestPermissions": [
// ...
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:app_name",
"usedScene": {
"abilities": [ "EntryAbility"],
"when":"inuse"
}
}
]
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
基础封装
使用 class 封装扫描能力
- 新建低功耗蓝牙封装模块
class EcBlueDevice {
scanDevice() {
}
}
export const ecDevice = new EcBlueDevice()
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 调用 ble 扫描方法
文档中心 startBLEScan(filters: Array, options?: ScanOptions): void 发起BLE扫描流程。
需要权限:ohos.permission.ACCESS_BLUETOOTH
系统能力:SystemCapability.Communication.Bluetooth.Core。
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
filters | Array<ScanFilter> | 是 | 表示扫描结果过滤策略集合,如果不使用过滤的方式,该参数设置为null。 |
options | ScanOptions | 否 | 表示扫描的参数配置,可选参数。 |
错误码: 以下错误码的详细介绍请参见蓝牙服务子系统错误码。
错误码ID | 错误信息 |
---|---|
2900001 | Service stopped. |
2900003 | Bluetooth switch is off. |
2900099 | Operation failed. |
示例:
import { BusinessError } from '@ohos.base';
function onReceiveEvent(data: Array<ble.ScanResult>) {
console.info('BLE scan device find result = '+ JSON.stringify(data));
}
try {
ble.on("BLEDeviceFind", onReceiveEvent);
let scanFilter: ble.ScanFilter = {
deviceId:"XX:XX:XX:XX:XX:XX",
name:"test",
serviceUuid:"00001888-0000-1000-8000-00805f9b34fb"
};
let scanOptions: ble.ScanOptions = {
interval: 500,
dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
}
ble.startBLEScan([scanFilter],scanOptions);
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 根据示例封装基础扫描方法
scanDevice() {
// 1. 监听扫描结果
ble.on("BLEDeviceFind", (devices: ble.ScanResult[])=>{
// 打印扫到设备
devices.forEach(item => {
Log.warn(`扫描中...\n ${item.deviceName || '--'} ${item.deviceId}`)
})
});
// 2. 开启扫描
let scanOptions: ble.ScanOptions = {
interval: 500,
dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
}
ble.startBLEScan(null, scanOptions);
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
问题:
- 扫描会一直执行
- 扫描结果重复
- 添加定时器控制扫描的时间
// 扫描定时器 id
timer: number = 0
scanDevice() {
if (this.timer) {
clearTimeout(this.timer)
}
// 1. 监听扫描结果
// …
// 2. 开启扫描
// …
<span class="hljs-comment"><span class="hljs-comment">// 3. 开启定时器控制时长</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.timer = setTimeout(() => {
ble.off(<span class="hljs-string"><span class="hljs-string">'BLEDeviceFind'</span></span>)
ble.stopBLEScan()
}, <span class="hljs-number"><span class="hljs-number">10000</span></span>)
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 添加扫描结果的回调函数
// 类型定义
export type ScanCallback = (list: ble.ScanResult[]) => void
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
+ scanDevice(callback: ScanCallback) {
if (this.timer) {
clearTimeout(this.timer)
}
// 1. 监听扫描结果
+ let list: ble.ScanResult[] = []
ble.on("BLEDeviceFind", (devices: ble.ScanResult[]) => {
// 打印扫到设备
devices.forEach(item => {
Log.warn(`扫描中...\n ${item.deviceName || '--'} ${item.deviceId}`)
})
+ list.push(...devices)
});
// 2. 开启扫描
// ...
// 3. 开启定时器控制时长
this.timer = setTimeout(() => {
+ callback(list)
ble.off(‘BLEDeviceFind’)
ble.stopBLEScan()
}, 10000)
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 对扫描结果进行去重
- 过滤没有重复的有效设备
- 追加进列表
// 1. 监听扫描结果
let list: ble.ScanResult[] = []
ble.on("BLEDeviceFind", (devices: ble.ScanResult[]) => {
// 打印扫到设备
devices.forEach(item => {
Log.warn(`扫描中...\n ${item.deviceName || '--'} ${item.deviceId}`)
})
+ const validDevices = devices.filter(dv => {
+ return list.some(item => item.deviceId === dv.deviceId) === false
})
+ if (validDevices.length > 0) {
list.push(...validDevices)
}
});
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
增强封装
需求:根据条件过滤扫描设备,获取指定条件设备
- 支持按照mac地址精确搜索匹配=》匹配一个
- 支持按照设备名称模糊匹配=》匹配多个
interface ScanFilter {
type: 'mac' | 'name'
value: string
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
mac 地址匹配
- 某血糖 mac 地址匹配
血糖适用:通过广播获取设备 mac 地址并匹配
/**
* 通过广播数据获取设备mac
* [@param](/user/param) data
* [@returns](/user/returns) FF-FF-11-57-B6-5B
*/
getMac(data: ArrayBuffer) {
// 1. Uint8Array处理二进制
const arr = new Uint8Array(data).slice(6, 12)
let mac = ''
// 2. 转换 16 进制
arr.forEach((item, i) => {
mac += i === 0 ? '' : '-'
mac += item.toString(16)
.padStart(2, '0')
.toUpperCase()
})
return mac
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 某门禁 mac 地址匹配
门禁适用:通过蓝牙名称匹配
/**
*
* [@param](/user/param) nodeId 10-8A-9B-8F-EC-3C
* [@param](/user/param) deviceName JL-ITHEIMA-8A10(BLE)
* [@returns](/user/returns)
*/
isMatchDoor(nodeId: string, deviceName: string) {
const adrs = nodeId.split('-')
const flag = adrs[1] + adrs[0]
return deviceName.includes(flag)
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
添加过滤条件
通过指定过滤条件参数,对设备进行过滤处理
- 根据条件过滤设备
const validDevices = devices.filter(dv => {
if (scanFilter.type === 'mac') {
let flag: boolean
if (!scanFilter.door) {
flag = this.getMac(dv.data) === scanFilter.value
} else {
flag = this.isMatchDoor(scanFilter.value, dv.deviceName)
}
return list.some(item => item.deviceId === dv.deviceId) === false && flag
} else {
return list.some(item => item.deviceId === dv.deviceId) === false &&
dv.deviceName.startsWith(scanFilter.value)
}
})
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 精确匹配模式:匹配到后结束扫描
if (validDevices.length > 0) {
list.push(...validDevices)
// 精确匹配到后直接结束扫描
if (scanFilter.type === 'mac') {
callback(list)
clearTimeout(this.timer)
ble.off('BLEDeviceFind')
ble.stopBLEScan()
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
- 测试
总结
鸿蒙系统通过提供统一且易于使用的API接口,startBLEScan、stopBLEScan以及配置ScanSettings和ScanFilter,极大简化了开发者实现蓝牙设备扫描的代码编写工作。开发者无需深入了解底层蓝牙协议细节,即可快速集成扫描功能到应用中。
同时通过高度优化的API集和详细的开发指南,为开发者搭建了一个强大且灵活的平台,以实现高效的BLE设备扫描功能,推动智能家居、健康监测等领域应用的创新与发展。
</markdown>关于HarmonyOS 鸿蒙Next物联网Iot开发-BLE设备扫描的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。
更多关于HarmonyOS 鸿蒙Next物联网Iot开发-BLE设备扫描的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next物联网Iot开发-BLE设备扫描的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
如果车机端是通过蓝牙协议的话,流程类似的哈
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
可以有哈