React-Native开发鸿蒙NEXT-蓝牙信标读取
项目中用到了ble蓝牙,应用启动后开始定时轮询周边蓝牙设备,根据读取到的数据判断是否是后台绑定的蓝牙设备,并返回给RN端做业务处理。
关于使用前蓝牙权限请求可以参考之前的文章,申请"ohos.permission.ACCESS_BLUETOOTH"权限。
React-Native开发鸿蒙NEXT-权限处理
悬空八只脚,公众号:悬空八只脚React-Native开发鸿蒙NEXT-权限处理
根据业务需要,RN端比较简单,仅仅在app启动判断获取到蓝牙权限后,触发ArkTS端的定时器,开始进行蓝牙扫描,在ArkTS端对扫描到的蓝牙设备进行过滤与数据处理,将最终结果传给RN。
RN端创建BluetoothTurboModule.tsx,仅提供开启/关闭轮询的方法,以及立即触发单次蓝牙查询。
BluetoothTurboModule.tsx
import {TurboModule, TurboModuleRegistry} from 'react-native';
export interface SpecBluetoothTurboModule extends TurboModule {
startTimer(seconds: number): void;
stopTimer(): void;
query(): void;}
export default TurboModuleRegistry.getEnforcing<SpecBluetoothTurboModule>( 'BluetoothTurboModule',);
再来看下ArkTS端的处理。ArkTS端主要处理都在BluetoothTurboModule.ets中完成。包括开启与关闭定时器,进行蓝牙搜索。核心是利用"@kit.ConnectivityKit"类来实现蓝牙搜索操作,通过绑定"BLEDeviceFind"来获取并处理搜索到蓝牙设备。
在使用过程中,发现一个问题,在最新的Ohos_sdk_public 5.0.0.71 (API Version 12 Release)这个版本上,我这的蓝牙硬件设备返回的name字段成了"",但在上个版本的sdk中还是可以正常返回的。不清楚是否是sdk的问题。如果需要使用到name字段来过滤蓝牙列表的同学需要注意下。
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/
import { TurboModule } from '@rnoh/react-native-openharmony/ts';
import emitter from '@ohos.events.emitter';
import { preferences } from '../entryability/EntryAbility'
import { BusinessError } from '@ohos.base';
import {BluetoothBean} from '../model/DataModel'
import { ble } from '@kit.ConnectivityKit';
import ConstUtil from '../utils/ConstUtil'
export interface TurboModuleEventData {
param: string
}
export class BluetoothTurboModule extends TurboModule {
_bluetoothTimer:number = -1;
query() {
try {
ble.stopBLEScan();
console.info('BLEDeviceQuery');
// 可以使用蓝牙名称来对蓝牙进行过滤,减少搜索到的蓝牙数量
let scanFilter: ble.ScanFilter = {
// name:"XXXXX",
};
let scanOptions: ble.ScanOptions = {
interval: 2000,
dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE
}
ble.startBLEScan([scanFilter],scanOptions);
console.info('ble.startBLEScan');
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
//errCode: 2900003, errMessage: BusinessError 2900003: Bluetooth switch is off.
}
}
startTimer(seconds: number) {
console.log("startTimer from BluetoothTurboModule: " + seconds);
try {
ble.off('BLEDeviceFind', this.onReceiveEvent);
ble.on("BLEDeviceFind", this.onReceiveEvent);
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
//errCode: 2900003, errMessage: BusinessError 2900003: Bluetooth switch is off.
}
if(seconds > 0){
this._bluetoothTimer = setInterval(() => {
console.log('do every ' + seconds * 1000 + 's');
this.query();
}, seconds * 1000);
}
}
stopTimer() {
console.log("stopTimer from BluetoothTurboModule: ")
if(this._bluetoothTimer != -1){
clearInterval(this._bluetoothTimer);
}
try {
ble.stopBLEScan();
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
}
onReceiveEvent(data: Array<ble.ScanResult>) {
console.info('BLE scan device find result = '+ JSON.stringify(data));
let _bleArray:Array<BluetoothBean> = [];
if(data == null || data.length == 0){
// 未扫描到蓝牙
// 发送给Index.ets,通过Index发送给RN
emitter.emit(ConstUtil.event_id_ble_scan_result,{data:_bleArray});
}else{
// 扫描到蓝牙设备
let _bleArray:Array<BluetoothBean> = [];
data.forEach((object:ble.ScanResult)=>{
if(object.data && object.data.byteLength > 0){
// 这里添加对蓝牙数据的处理,如获取uuid,major,minor。。。。。。
}
});
// 发送给Index.ets,通过Index发送给RN
emitter.emit(ConstUtil.event_id_ble_scan_result,{data:_bleArray});
}
try {
ble.stopBLEScan();
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
}
}
优快云不经常在线,有问题可在微信公众号或者掘金社区私信留言
更多内容可关注
我的公众号悬空八只脚
作者:悬空八只脚
链接:https://juejin.cn/post/7439556806602817587
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。