更新记录
1.0.0(2026-09-30) 下载此版本
- 首次发布:BLE 透传会话 API(
openAdapter/startScan/connect/write/disconnect) - Android:Nordic BLE Library
2.3.1+ Scanner1.4.3(扫描 UTS 直调;连接/写/通知经薄 Kotlin 封装) - iOS:CoreBluetooth
- HarmonyOS:ConnectivityKit
- 数据:hex 字符串收发;官方
options.success/fail/complete,持续回调onFound/onNotify/onDisconnect
平台兼容性
uni-app x(5.21)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | 5.0 | 12 | √ | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
BLE 透传(Android / iOS / 鸿蒙)
面向 uni-app x(含蒸汽模式) 的三端 UTS BLE 透传插件。统一 openAdapter / startScan / connect / write / disconnect 会话式 API,报文以 hex 字符串 收发,适合智能硬件透传、自定义 BLE 协议、门锁/表计/模组等场景。
| 平台 | 底层 | 说明 |
|---|---|---|
| Android | Nordic BLE Library 2.3.1 + Scanner 1.4.3 |
扫描 UTS 直调;连接/写/通知经薄 Kotlin 封装(BleManager 的回调与写特征为 protected,UTS 无法模块级继承) |
| iOS | CoreBluetooth | 系统框架,无三方依赖 |
| HarmonyOS | ConnectivityKit | 系统蓝牙能力 |
功能特性
| 特性 | 说明 |
|---|---|
| 三端统一 API | openAdapter / startScan / connect / write / disconnect / isConnected / getDeviceId |
| 透传设计 | 只负责扫描、连接、写入与 notify 回传;协议拼装、分包、业务重试由调用方处理 |
| 数据格式 | hex 字符串(小写无分隔写入;notify 回传统一小写 hex) |
| 官方回调约定 | options.success / fail / complete,插件层 无 Promise;业务可自行包装 |
| 持续回调 | startScan.onFound、connect.onNotify / onDisconnect(@UTSJS.keepAlive 保活) |
| 写入方式 | 默认 BLE_WRITE_WITHOUT_RESPONSE,可选 BLE_WRITE_WITH_RESPONSE |
| 连接寻址 | deviceId 直连,或 namePrefix 扫描后连接 |
| 错误码 | 统一 905xxxx + 用户可读中文 errMsg |
| 线程 | 回调统一切主线程 |
平台兼容性
| 平台 | 支持 | 说明 |
|---|---|---|
| Android | ✅ | minSdkVersion 21;maven 依赖需 自定义基座 或云打包 |
| iOS | ✅ | deploymentTarget 12.0;系统 CoreBluetooth |
| HarmonyOS | ✅ | ConnectivityKit;自定义基座 或云打包 |
| Web / 小程序 | ❌ | 无原生 BLE 透传能力 |
- HBuilderX:
^4.27(@UTSJS.keepAlive需要) - uni-app x:App-Android / App-iOS / App-HarmonyOS(含蒸汽模式)
快速开始
import {
openAdapter, closeAdapter,
startScan, stopScan,
connect, write, disconnect,
isConnected, getDeviceId,
BLE_WRITE_WITHOUT_RESPONSE
} from '@/uni_modules/bin-ble'
// 1. 打开适配器(幂等;蓝牙未开/未授权走 fail)
openAdapter({
success: (ok) => {
if (!ok) return
// 2. 扫描
startScan({
namePrefix: 'DEV', // 或 serviceUuids
timeout: 10000,
allowDuplicates: false,
onFound: (device) => {
// { deviceId, name, rssi, advertisData }
console.log(device.deviceId, device.name, device.rssi)
},
onEnd: () => console.log('scan end'),
fail: (err) => uni.showToast({ title: err.errMsg, icon: 'none' })
})
},
fail: (err) => uni.showToast({ title: err.errMsg, icon: 'none' })
})
// 3. 连接(deviceId 直连,或 namePrefix 扫描后连接)
connect({
deviceId: 'AA:BB:CC:DD:EE:FF', // 与 namePrefix 二选一
// namePrefix: 'DEV',
serviceUuid: '0000fff0-0000-1000-8000-00805f9b34fb',
writeUuid: '0000fff1-0000-1000-8000-00805f9b34fb',
notifyUuid: '0000fff2-0000-1000-8000-00805f9b34fb',
writeType: BLE_WRITE_WITHOUT_RESPONSE, // 默认
mtu: 247, // 可选
scanTimeout: 10000, // namePrefix 扫描超时
success: (result) => {
// { deviceId, name, mtu, writeType }
write('a50100ff', {
success: () => {},
fail: (err) => uni.showToast({ title: err.errMsg, icon: 'none' })
})
},
fail: (err) => uni.showToast({ title: err.errMsg, icon: 'none' }),
onNotify: (hex) => {
// 持续回调:设备 notify,小写 hex
console.log('notify', hex)
},
onDisconnect: () => {
// 持续回调:被动断开(主动 disconnect 不触发)
}
})
// 4. 主动断开并清理会话
disconnect()
closeAdapter()
业务侧包 Promise(可选)
插件遵循官方 UTS 回调约定,不返回 Promise。需要串行流程时可在业务侧包装:
function connectAsync(opts) {
return new Promise((resolve, reject) => {
connect({
...opts,
success: (r) => resolve(r),
fail: (e) => reject(e),
onNotify: opts.onNotify,
onDisconnect: opts.onDisconnect
})
})
}
complete入参为any,业务侧勿用.取属性。持续回调放在connect.options上是安全的:connect为 void + keepAlive,不是 Promise。
API
常量
| 常量 | 值 | 说明 |
|---|---|---|
BLE_WRITE_WITH_RESPONSE |
0 |
写入需应答 |
BLE_WRITE_WITHOUT_RESPONSE |
1 |
写入无需应答(默认) |
openAdapter(options): void
检查并准备蓝牙适配器。蓝牙可用时 success(true);系统蓝牙未开时按平台尝试引导开启,失败回 fail。
| 参数 | 类型 | 说明 |
|---|---|---|
success |
(ok: boolean) => void |
ok=true 蓝牙可用 |
fail |
(err: BleFail) => void |
见错误码 |
complete |
(res: any) => void |
结束回调 |
closeAdapter(): void
释放适配器相关资源。不影响已建立业务语义的会话清理;离开蓝牙功能页时建议调用。
startScan(options): void
开始扫描。onFound 持续回调;超时或主动 stopScan 后触发 onEnd 与 complete。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
namePrefix |
string? |
— | 按名称前缀过滤 |
serviceUuids |
string[]? |
— | 按服务 UUID 过滤 |
allowDuplicates |
boolean? |
false |
是否重复上报同一设备 |
timeout |
number? |
平台默认 | 扫描超时毫秒 |
onFound |
(device: BleDevice) => void |
必填 | 持续回调 |
fail |
(err: BleFail) => void |
— | 扫描错误 |
onEnd |
() => void |
— | 扫描结束 |
complete |
(res: any) => void |
— | 结束回调 |
BleDevice:
| 字段 | 类型 | 说明 |
|---|---|---|
deviceId |
string |
Android MAC / iOS UUID / 鸿蒙设备标识 |
name |
string \| null |
广播名 |
rssi |
number |
信号强度 |
advertisData |
string \| null |
广播数据 hex(无分隔) |
stopScan(): void
主动停止扫描。幂等。
connect(options): void
建立透传会话。同时只保留一个会话:新 connect 会替换旧会话,旧会话以 9050011 结束。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
deviceId |
string? |
— | 直连;与 namePrefix 二选一 |
namePrefix |
string? |
— | 先扫描再连接 |
serviceUuid |
string |
必填 | 透传服务 UUID |
writeUuid |
string |
必填 | 写特征 UUID |
notifyUuid |
string |
必填 | 通知特征 UUID |
writeType |
number? |
1 |
0 with response / 1 without response |
mtu |
number? |
平台默认 | 期望 MTU |
scanTimeout |
number? |
平台默认 | namePrefix 扫描超时毫秒 |
success |
(result: BleConnectResult) => void |
— | 连接就绪 |
fail |
(err: BleFail) => void |
— | 见错误码 |
complete |
(res: any) => void |
— | 结束回调 |
onNotify |
(hex: string) => void |
— | 持续:设备通知 |
onDisconnect |
() => void |
— | 持续:被动断开 |
BleConnectResult:{ deviceId, name, mtu, writeType }
write(hex, options?): void
写入一包数据。同一时刻只允许一次未完成写入,冲突回 9050011。
| 参数 | 类型 | 说明 |
|---|---|---|
hex |
string |
十六进制串(可含大小写,禁止分隔符) |
success |
() => void |
写入成功 |
fail |
(err: BleFail) => void |
见错误码 |
complete |
(res: any) => void |
结束回调 |
disconnect(options?): void
主动断开并清理会话。success / complete 可选。不触发 onDisconnect。幂等。
isConnected(): boolean / getDeviceId(): string
当前会话是否已连接;当前连接设备 deviceId(未连接时为空串)。
错误码
fail 参数为 BleFail(继承 UniError),errSubject = 'bin-ble'。业务 toast 优先展示 errMsg。
| errCode | 含义 | 典型触发 |
|---|---|---|
| 9050001 | 蓝牙未开启 | 系统蓝牙关闭(iOS poweredOff 等) |
| 9050002 | 应用蓝牙权限未授予 | iOS unauthorized;Android / 鸿蒙运行时权限被拒 |
| 9050003 | 搜索设备失败 | 扫描错误、超时未搜到 |
| 9050004 | 连接设备失败 | 连接超时、连接中断、服务初始化失败 |
| 9050005 | 连接已断开 | 被动断开后写入、会话被取消 |
| 9050006 | 未识别到该设备 | 服务/特征未找到、型号不匹配 |
| 9050007 | 读取设备数据失败 | 读特征失败 |
| 9050008 | 指令发送失败 | 写特征失败 |
| 9050009 | 设备通信初始化失败 | 订阅 notify 失败、写入方式不支持 |
| 9050010 | 操作参数有误 | UUID 无效、hex 非法、缺少 deviceId/namePrefix |
| 9050011 | 设备忙 | 并发写入、新连接替换旧连接、扫描被取消 |
errMsg 为中文用户文案;个别分支会附加简短中文说明(如「未搜索到设备」)。
集成说明
Android
- 依赖经 Gradle maven 拉取:
no.nordicsemi.android:ble:2.3.1no.nordicsemi.android:log:2.2.0no.nordicsemi.android.support.v18:scanner:1.4.3
- 真机调试请用 自定义基座 / 云打包(标准基座无三方依赖)。
- 权限:
- API 31+:
BLUETOOTH_SCAN/BLUETOOTH_CONNECT运行时申请 - API 23–30:
ACCESS_FINE_LOCATION(扫描需要) - 低版本:
BLUETOOTH/BLUETOOTH_ADMIN
- API 31+:
- 未使用 Nordic DFU;固件升级请另选方案。
iOS
- 系统 CoreBluetooth,无 CocoaPods 三方依赖。
- 需在业务工程配置
NSBluetoothAlwaysUsageDescription。 - 含
PrivacyInfo.xcprivacy(仅 UserDefaults,无 Tracking)。 deviceId为 iOS 芯片 UUID,不可当作跨平台 MAC 使用;跨端请以扫描结果缓存或业务侧映射为准。
HarmonyOS
- 使用系统 ConnectivityKit 蓝牙能力。
- 需
ohos.permission.ACCESS_BLUETOOTH,并在应用权限声明中配置。 - 部分机型/系统版本对写特征属性较严:设备不支持所选
writeType时会回9050009。
行为约定
- 插件层无 Promise:全部为
void+ 官方success/fail/complete;持续回调靠@UTSJS.keepAlive保活(需 HBuilderX ≥ 4.27)。 - 单会话:全局仅一个透传连接;重复
connect会替换旧连接(旧连接fail(9050011))。 - 主动
disconnect不触发onDisconnect;仅被动断开(对端断电、链路丢失等)触发。 write串行:前一次写入未完成时再次write回9050011。- hex 约定:写入与 notify 均为无分隔十六进制;奇数长度或含非 hex 字符回
9050010。 complete入参为any,请勿用.取属性。- 扫描/连接中的页面退出时,调用
stopScan/disconnect/closeAdapter清理,避免后台扫描与会话泄漏。
最佳实践
- 先
openAdapter再扫描/连接,在fail里引导用户开蓝牙或授权。 - 优先
deviceId直连(扫描结果缓存后连接),比namePrefix更快、更稳。 - 协议层自行分包:插件每次
write发送一包;大于 MTU 的业务报文请在调用方切分。 - notify 流水线:
onNotify可能粘包/半包,业务侧按自定义协议组帧。 - 离页清理:
onUnload里stopScan+disconnect(若仍连接)+closeAdapter。

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 178
赞赏 0
下载 12649954
赞赏 1953
赞赏
京公网安备:11010802035340号