@react-native-ohos/react-native-ble-plx
v3.6.0
Published
React Native Bluetooth Low Energy library
Readme
模板版本:v0.4.1
本项目基于 react-native-ble-plx 开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-ble-plx。 版本所属关系如下:
| 三方库名称 | 三方库版本 | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | npm地址 | | ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- | | @react-native-ohos/react-native-ble-plx | ~3.6.0(开发中) | Gitcode Releases | 0.82.* | 是 | API12+ | 3.5.0 | Npm Address | | @react-native-ohos/react-native-ble-plx | ~3.5.1 | Gitcode Releases | 0.77.* | 否 | API12+ | 3.5.0 | Npm Address | | @react-native-ohos/react-native-ble-plx | ~3.2.1 | Gitcode Releases | 0.72.* | 是 | API12+ | 3.2.0 | Npm Address | | @react-native-oh-tpl/react-native-ble-plx | <= 3.2.0-0.0.4@deprecated| Github Releases(deprecated) | 0.72.* | 否 | API12+ | 3.2.0 | Npm Address |
简介
react-native-ble-plx 是一款专为 React Native 生态打造的跨平台蓝牙低功耗(BLE)开发库。
下载安装
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/react-native-ble-plxyarn
yarn add @react-native-ohos/react-native-ble-plxLink
| | 是否支持autolink | RN框架版本 | |--------------------------------------|-----------------|------------| | ~3.6.0 | 是 | 0.82 |
使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。
首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony。
在工程根目录的 oh-package.json5 添加 overrides 字段
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}引入原生端代码
目前有两种方法:
- 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
- 直接链接源码。
方法一:通过 har 包引入(推荐)
[!TIP] har 包位于三方库安装路径的
harmony文件夹下。
打开 entry/oh-package.json5,添加以下依赖
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@react-native-ohos/react-native-ble-plx": "file:../../node_modules/@react-native-ohos/react-native-ble-plx/harmony/rn_bleplx.har"
}点击右上角的 sync 按钮
或者在终端执行:
cd entry
ohpm install方法二:直接链接源码
[!TIP] 如需使用直接链接源码,请参考直接链接源码说明
配置 CMakeLists 和引入 BlePlxPackage
打开 entry/src/main/cpp/CMakeLists.txt,添加:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-ble-plx/src/main/cpp" ./rn_bleplx)
# RNOH_END: manual_package_linking_1
file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
add_library(rnoh_app SHARED
${GENERATED_CPP_FILES}
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_ble_plx)
# RNOH_END: manual_package_linking_2打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "generated/BlePlxRNOHGeneratedPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<RNOHGeneratedPackage>(ctx),
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<BlePlxRNOHGeneratedPackage>(ctx)
};
}在 ArkTs 侧引入 BlePlxPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
...
+ import {BlePlxPackage} from '@react-native-ohos/react-native-ble-plx/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SamplePackage(ctx),
+ new BlePlxPackage(ctx)
];
}运行
点击右上角的 sync 按钮
或者在终端执行:
cd entry
ohpm install然后编译、运行即可。
约束与限制
兼容性
本文档内容基于以下环境验证通过:
- RNOH: 0.82.1; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;
权限要求
由于此库涉及蓝牙系统控制功能,使用对应接口时则需要配置对应的权限,权限需配置在entry/src/main目录下module.json5文件中。其中部分权限需弹窗向用户申请授权。具体权限配置见文档:程序访问控制。
此库部分功能与接口需要normal权限:ohos.permission.ACCESS_BLUETOOTH。
使用示例
下面的代码展示了这个库的基本使用场景:
[!WARNING] 使用时 import 的库名不变。
import React from 'react';
import { View, Button, Alert } from 'react-native';
import {
BleErrorCode,
BleManager,
Device,
Service,
Descriptor,
type DeviceId,
type UUID,
type Characteristic,
} from 'react-native-ble-plx';
import Toast from 'react-native-simple-toast';
class BLEServiceInstance {
manager: BleManager
device: Device | null
constructor() {
this.device = null
this.manager = new BleManager()
}
scanDevices = async (onDeviceFound: (device: Device) => void, UUIDs: UUID[] | null = null) => {
this.manager.startDeviceScan(UUIDs, null, (error: any, device: any) => {
if (error) {
console.error(error.message)
this.manager.stopDeviceScan()
return
}
if (device) {
onDeviceFound(device)
}
})
}
connectToDevice = (deviceId: DeviceId) =>
new Promise<Device>((resolve, reject) => {
this.manager.stopDeviceScan()
this.manager
.connectToDevice(deviceId)
.then((device: any) => {
this.device = device
resolve(device)
})
.catch((error: any) => {
if (error.errorCode === BleErrorCode.DeviceAlreadyConnected && this.device) {
resolve(this.device)
} else {
console.error(error.message)
reject(error)
}
})
})
}
class App extends React.Component {
//该库使用需注意以下属性设置
deviceName: string = 'time'//蓝牙设备名称
serviceUuid: string = '00001820-0000-1000-8000-00805F9B34FB'//注意大小写必须大写,服务端一样必须大写(扫描到英文字符会默认UPPERCASE导致指定serviceUuid找不到服务)
characteristicUuid: string = '00001820-0000-1000-8000-00805F9B34FB'//需要英文字符大写
descriptorUuid: string = '00002903-0000-1000-8000-00805F9B34FB'//需要英文字符大写
device?: Device;
service?: Service;
characteristic?: Characteristic;
descriptor?: Descriptor;
showLog(text: string) {
Toast.show(text, Toast.SHORT);
console.log('bleplx showLog:' + text);
};
ble = new BLEServiceInstance((text: string) => {
this.showLog(text);
});
enable = () => {
this.ble.manager.enable();
Toast.show('enable', Toast.SHORT)
}
disable = () => {
this.ble.manager.disable();
Toast.show('disable', Toast.SHORT)
}
startScan = () => {
console.log('startScan');
Toast.show('开始扫描外设', Toast.LONG)
this.ble.manager.startDeviceScan(null, null, (error: any, device: any) => {
if (device?.name) {
console.log('bleplx: startScan result:' + device?.name);
}
if (device?.name?.toLocaleLowerCase() == this.deviceName) {
if (this.device != null) {
return
}
this.device = device;
this.stopDeviceScan();
Alert.alert(
'发现外设:' + device.name,
'是否连接?',
[
{
text: '取消',
style: 'cancel'
},
{
text: '连接',
onPress: () => {
this.connectToDevice();
},
style: 'destructive'
}
]
)
}
})
}
stopDeviceScan = () => {
this.ble.manager.stopDeviceScan();
Toast.show('stopDeviceScan', Toast.SHORT)
}
connectToDevice = () => {
if (this.device == null) {
console.log('bleplx: 没有找到指定的连接设备');
return;
}
console.log('bleplx: 开始连接:' + this.device.id);
Toast.show('开始连接外设', Toast.LONG)
this.ble.manager.connectToDevice(this.device.id).then((device: any) => {
Toast.show('连接成功', Toast.SHORT);
console.log('bleplx:连接成功:' + JSON.stringify(device));
}).catch((error: any) => {
Toast.show('连接失败', Toast.SHORT);
console.log('bleplx:连接失败:' + error.message);
});
}
render() {
return (
<View>
<Button title='enable' onPress={this.enable}>enable</Button>
<Button title='disable' onPress={this.disable}>disable</Button>
<Button title='startScan' onPress={this.startScan}>startScan</Button>
<Button title='stopDeviceScan' onPress={this.stopDeviceScan}>stopDeviceScan</Button>
</View>
)
}
}
export default App;API
[!TIP] "Platform"列表示该属性在原三方库上支持的平台。
[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| Name | Description | Type | Required | Platform | HarmonyOS Support | | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | ----------------- | -------- | ----------- | ----------------- | | createClient(restoreStateIdentifier?: string) | 创建 BLE 客户端,可选择传入恢复状态标识符以恢复之前的蓝牙状态。 | void | No | iOS/Android | yes | | destroyClient() | 销毁 BLE 客户端,释放相关资源。 | Promise | No | iOS/Android | yes | | cancelTransaction(transactionId: string) | 取消指定的蓝牙事务。 | Promise | No | iOS/Android | no | | setLogLevel(logLevel: string) | 设置日志级别。 | Promise | No | iOS/Android | no | | logLevel() | 获取当前日志级别。 | Promise | No | iOS/Android | no | | enable(transactionId: string) | 启用蓝牙模块并获取事务 ID。 | Promise | No | iOS/Android | yes | | disable(transactionId: string) | 禁用蓝牙模块。 | Promise | No | iOS/Android | yes | | state() | 获取当前蓝牙状态。 | Promise | No | iOS/Android | yes | | startDeviceScan(filteredUUIDs: string[], options: Object) | 开始扫描周围的蓝牙设备,可按 UUID 过滤。 | Promise | No | iOS/Android | yes | | stopDeviceScan() | 停止扫描蓝牙设备。 | Promise | No | iOS/Android | yes | | requestConnectionPriorityForDevice(deviceId: string, connectionPriority: number,transactionId: string) | 请求设置指定设备的连接优先级。 | Promise | No | iOS/Android | no | | readRSSIForDevice(deviceId: string, transactionId: string) | 读取指定设备的 RSSI(信号强度)值。 | Promise | No | iOS/Android | yes | | requestMTUForDevice(deviceId: string, mtu: number, transactionId: string) | 请求设置指定设备的 MTU(最大传输单元)大小。 | Promise | No | iOS/Android | yes | | devices(deviceIdentifiers: string[]) | 根据设备标识符列表获取对应的已知设备信息。 | Promise<Object[]> | No | iOS/Android | yes | | connectedDevices(serviceUUIDs: string[]) | 获取已连接的蓝牙设备列表,可按服务 UUID 过滤。 | Promise<Object[]> | No | iOS/Android | yes | | connectToDevice(deviceId: string, options?: Object) | 连接到指定的蓝牙设备,可传入连接选项配置。 | Promise | No | iOS/Android | yes | | cancelDeviceConnection(deviceId: string) | 断开与指定设备的蓝牙连接。 | Promise | No | iOS/Android | yes | | isDeviceConnected(deviceId: string) | 检查指定设备是否已连接。 | Promise | No | iOS/Android | yes | | discoverAllServicesAndCharacteristicsForDevice(deviceId: string, transactionId: string) | 发现并获取指定设备的所有服务和特征值。 | Promise | No | iOS/Android | yes | | servicesForDevice(deviceId: string) | 获取指定设备的所有服务列表。 | Promise<Object[]> | No | iOS/Android | yes | | characteristicsForDevice(deviceId: string, serviceUUID: string) | 获取指定设备上某服务的所有特征值。 | Promise<Object[]> | No | iOS/Android | yes | | characteristicsForService(serviceIdentifier: number) | 根据服务标识符获取该服务的所有特征值。 | Promise<Object[]> | No | iOS/Android | yes | | descriptorsForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string): Promise<Object[]> | 获取指定设备上某服务某特征值的所有描述符。 | Promise<Object[]> | No | iOS/Android | yes | | descriptorsForService(serviceIdentifier: number, characteristicUUID: string) | 根据服务标识符获取某特征值的所有描述符。 | Promise<Object[]> | No | iOS/Android | yes | | descriptorsForCharacteristic(characteristicIdentifier: number) | 根据特征值标识符获取该特征值的所有描述符。 | Promise<Object[]> | No | iOS/Android | yes | | readCharacteristicForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string, transactionId: string) | 读取指定设备上某服务某特征值的值。 | Promise | No | iOS/Android | yes | | readCharacteristicForService(serviceIdentifier: number, characteristicUUID: string,transactionId: string) | 根据服务标识符读取某特征值的值。 | Promise | No | iOS/Android | yes | | readCharacteristic(characteristicIdentifier: number, transactionId: string) | 根据特征值标识符读取特征值的值。 | Promise | No | iOS/Android | yes | | writeCharacteristicForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string, valueBase64: string,response: boolean, transactionId: string) | 向指定设备上某服务某特征值写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | writeCharacteristicForService(serviceIdentifier: number, characteristicUUID: string, valueBase64: string,response: boolean, transactionId: string) | 根据服务标识符向某特征值写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | writeCharacteristic(characteristicIdentifier: number, valueBase64: string, response: boolean,transactionId: string) | 根据特征值标识符写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | monitorCharacteristicForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string,transactionId: string) | 监听指定设备上某服务某特征值的值变化通知。 | Promise | No | iOS/Android | yes | | monitorCharacteristicForService(serviceIdentifier: number, characteristicUUID: string,transactionId: string) | 根据服务标识符监听某特征值的值变化通知。 | Promise | No | iOS/Android | yes | | monitorCharacteristic(characteristicIdentifier: number, transactionId: string) | 根据特征值标识符监听值变化通知。 | Promise | No | iOS/Android | yes | | readDescriptorForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string, descriptorUUID: string,transactionId: string) | 读取指定设备上某服务某特征值某描述符的值。 | Promise | No | iOS/Android | yes | | readDescriptorForService(serviceIdentifier: number, characteristicUUID: string, descriptorUUID: string,transactionId: string) | 根据服务标识符读取某特征值某描述符的值。 | Promise | No | iOS/Android | yes | | readDescriptorForCharacteristic(characteristicIdentifier: number, descriptorUUID: string,transactionId: string) | 根据特征值标识符读取某描述符的值。 | Promise | No | iOS/Android | yes | | readDescriptor(descriptorIdentifier: number, transactionId: string) | 根据描述符标识符读取描述符的值。 | Promise | No | iOS/Android | yes | | writeDescriptorForDevice(deviceId: string, serviceUUID: string, characteristicUUID: string, descriptorUUID: string,valueBase64: string, transactionId: string) | 向指定设备上某服务某特征值某描述符写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | writeDescriptorForService(serviceIdentifier: number, characteristicUUID: string, descriptorUUID: string,valueBase64: string, transactionId: string) | 根据服务标识符向某特征值某描述符写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | writeDescriptorForCharacteristic(characteristicIdentifier: number, descriptorUUID: string, valueBase64: string,transactionId: string) | 根据特征值标识符向某描述符写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes | | writeDescriptor(descriptorIdentifier: number, valueBase64: string, transactionId: string) | 根据描述符标识符写入数据(Base64 编码)。 | Promise | No | iOS/Android | yes |
遗留问题
- [ ] cancelTransaction(transactionId: string)接口harmony暂不支持: issue#2
- [ ] setLogLevel(logLevel: string)接口harmony暂不支持: issue#3
- [ ] logLevel()接口harmony暂不支持: issue#4
- [ ] requestConnectionPriorityForDevice(deviceId: string, connectionPriority: number,transactionId: string)接口harmony暂不支持: issue#5
其他
无
目录结构
/rntpc_react-native-ble-plx # 项目根目录
│ LICENSE
│ OAT.xml
│ package.json
│ README.md
│ README.OpenSource
│ README_en.md
│
├─example
│
├─harmony
│ │ rn_bleplx.har # 编译后的 HAR 包(HarmonyOS Archive)
│ │
│ └─rn_bleplx # 鸿蒙适配核心代码
│ │ build-profile.json5
│ │ BuildProfile.ets
│ │ hvigorfile.ts
│ │ index.ets
│ │ obfuscation-rules.txt
│ │ oh-package.json5
│ │ ts.ets
│ │
│ └─src
│ └─main
│ └─ets # ArkTS 业务层
│ │ BleDevice.ts
│ │ BleModule.ts
│ │ BlePlxInterface.ts
│ │ BlePlxModule.ets
│ │ BlePlxPackage.ets
│ │ Characteristic.ts
│ │ CommonConstants.ts
│ │ Descriptor.ts
│ │ Service.ts
│ │
│ └─common
│ BleError.ts
│ BleErrorToJsObjectConverter.ts
│ BleEvent.ts
│ BleUtils.ts
│ IdGenerator.ts
│ IdGeneratorKey.ts
│ InstanceIdGenerator.ts
│ Logger.ts
│ PermissionHandler.ts
│ ServiceFactory.ts
│
└─src #js侧实现
BleError.js
BleManager.js
BleModule.js
Characteristic.js
Descriptor.js
Device.js
index.d.ts
index.js
NativeBlePlx.ts
Service.js
TypeDefinition.js
Utils.js贡献代码
使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。
开源协议
本项目基于 Apache License 2.0 ,请自由地享受和参与开源。
