更新记录
1.0.1(2026-10-14) 下载此版本
- 承接项目侧下沉:
BLEDeviceBase(含自动重连钩子 /asAutoReconnecting) - 导出
toUint8Array:兼容跨 realm BLE 回调缓冲;summarizeBinary复用
1.0.0(2026-10-14) 下载此版本
- 首次发布
- 提供 BLEAdapter、BLEScanCoordinator 及设备发现策略
- 依赖 pro-device-core
平台兼容性
uni-app(5.06)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | - | √ | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
pro-device-adp-ble — BLE 传输原语
uni_modules BLE 蓝牙传输适配器。提供 BLEAdapter(连接/发送/接收)、BLEScanCoordinator(全局扫描协调器)以及三种设备发现策略。
可独立使用,亦可作为 pro-device 框架的 ITransport 适配器。
架构定位
pro-device-adp-ble
├── BLEAdapter ← 传输适配器(满足 ITransport 接口)
│ ├── open() ← 扫描发现 + BLE 建连 + 特征发现 + notify 使能
│ ├── close() ← 断开 BLE 连接,清理监听器
│ ├── send() ← 分包写入(MTU 自动协商)
│ ├── onReceive() ← 订阅 notify 数据
│ └── onDisconnect() ← 订阅意外断开事件
├── BLEScanCoordinator ← 进程级单例,解决多设备并发扫描互斥问题
│ ├── scan() ← 按 matcher 找已知目标
│ └── startDiscovery()← UI 列表发现(与 scan 共用引用计数)
└── 发现策略
├── matchByDeviceId ← 已知 deviceId(默认)
├── matchByAdvertisMAC ← 广播包 MAC 反解
├── parseAdvertisMAC ← MAC 解析(UI / matcher 共用)
└── matchByName ← 设备广播名称匹配
安装
本插件为项目内置 uni_modules,无需从插件市场安装。
依赖:pro-device-core(仅类型依赖,零运行时依赖)。
核心 API
BLEAdapter — BLE 传输适配器
实现 pro-device 的 ITransport 接口(TypeScript 结构类型系统,无 implements 关键字,满足鸭子类型即可)。
import { BLEAdapter } from '@/uni_modules/pro-device-adp-ble'
import type { BLEAdapterConfig } from '@/uni_modules/pro-device-adp-ble'
配置项 BLEAdapterConfig
interface BLEAdapterConfig {
/** 设备标识符;语义由 matcher 决定(deviceId / MAC / 名称) */
ident: string
/** 设备发现策略,默认 matchByDeviceId */
matcher?: BLEScanMatcher
/** 扫描超时时间(ms),默认 10000 */
scanTimeout?: number
[key: string]: unknown
}
方法
| 方法 | 签名 | 说明 |
|---|---|---|
open(config) |
Promise<void> |
启动蓝牙 → 发现设备 → 建立连接 → 协商 MTU → 发现特征 → 使能 notify |
close() |
Promise<void> |
断开 BLE 连接,清理所有监听器 |
send(data) |
Promise<void> |
将 ArrayBuffer 分包(按协商 MTU)写入可写特征 |
onReceive(cb) |
() => void |
订阅 notify 特征值变化,返回取消订阅函数 |
onDisconnect(cb) |
(reason: TransportDisconnectReason) => void |
订阅意外断开(主动 close 不触发),返回取消订阅函数 |
connected |
boolean |
当前连接状态 |
直接使用示例
import { BLEAdapter } from '@/uni_modules/pro-device-adp-ble'
import { matchByDeviceId } from '@/uni_modules/pro-device-adp-ble'
const adapter = new BLEAdapter()
await adapter.open({
ident: 'AA:BB:CC:DD:EE:FF',
matcher: matchByDeviceId,
scanTimeout: 10000,
})
const unsub = adapter.onReceive((data) => {
const bytes = new Uint8Array(data)
console.log('received:', bytes)
})
await adapter.send(new Uint8Array([0x1b, 0x40]).buffer)
// 清理
unsub()
await adapter.close()
与 pro-device-core 框架配合
import type { ITransport } from '@/uni_modules/pro-device-core'
import { BLEAdapter } from '@/uni_modules/pro-device-adp-ble'
// BLEAdapter 自动满足 ITransport(结构类型),无需 implements
const transport: ITransport = new BLEAdapter()
BLEScanCoordinator — 全局扫描协调器
解决的问题: uni.startBluetoothDevicesDiscovery / stopBluetoothDevicesDiscovery 是小程序平台级全局操作,任意一处调用 stop 会终止所有扫描。当多台设备同时连接时(如打印机 + 电子秤),第一台找到目标后 stop 会强制中止其他设备的扫描。
解决思路:引用计数单例。
第一个消费者加入 → 启动扫描
某消费者找到目标或超时 → 从列表移除
最后一个消费者退出 → 停止扫描
BLEAdapter.open() 内部自动使用协调器,通常无需直接调用。如需自定义发现逻辑:
import { BLEScanCoordinator } from '@/uni_modules/pro-device-adp-ble'
import { matchByName } from '@/uni_modules/pro-device-adp-ble'
const coordinator = BLEScanCoordinator.getInstance()
// 目标匹配:返回 Promise<deviceId>,超时抛出 BLEConnectionError
const deviceId = await coordinator.scan('MY-PRINTER-001', matchByName, 10000)
// 列表发现(与 scan 共用引用计数;仅当订阅与 scan 消费者都为 0 时才 stop)
const unsub = coordinator.startDiscovery({
onDevices(devices) {
console.log('nearby', devices)
},
onError(err) {
console.error(err)
},
})
unsub()
设备发现策略
matchByDeviceId(默认)
适用场景:已知设备的 deviceId(通常为 UUID 格式,在连接历史中缓存)。
import { matchByDeviceId } from '@/uni_modules/pro-device-adp-ble'
// ident 直接作为 deviceId,跳过扫描阶段,直接建连
await adapter.open({ ident: '12345678-1234-1234-1234-1234567890AB', matcher: matchByDeviceId })
注意: 小程序平台
deviceId格式因平台而异(微信为 UUID,支付宝为 MAC 地址)。matchByDeviceId跳过了扫描阶段,适合已知设备的快速重连。
matchByAdvertisMAC
适用场景:仅知 MAC 地址时,从广播包末 6 字节反解并进行匹配。
import { matchByAdvertisMAC } from '@/uni_modules/pro-device-adp-ble'
// ident 为设备 MAC 地址(支持 : 或 - 分隔符,大小写不敏感)
await adapter.open({
ident: 'AA:BB:CC:DD:EE:FF',
matcher: matchByAdvertisMAC,
scanTimeout: 10000,
})
matchByName
适用场景:通过设备广播名称匹配(如 Furi DGL-50B、Detonger P1)。
import { matchByName } from '@/uni_modules/pro-device-adp-ble'
await adapter.open({
ident: 'P1-DEVICE-001', // 设备广播名称
matcher: matchByName,
scanTimeout: 10000,
})
自定义发现策略
import type { BLEScanMatcher } from '@/uni_modules/pro-device-adp-ble'
// 自定义:按厂商数据前缀匹配
const matchByManufacturer: BLEScanMatcher = (devices, ident) => {
const prefix = ident.toUpperCase()
for (const d of devices) {
if (!d.advertisData) continue
const hex = Array.from(new Uint8Array(d.advertisData as ArrayBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('')
.toUpperCase()
if (hex.startsWith(prefix)) return d.deviceId
}
return null // 返回 null/undefined 表示"继续等待"
}
错误体系
import {
BLEError,
BLEConnectionError,
BLECommunicationError,
} from '@/uni_modules/pro-device-adp-ble'
try {
await adapter.open(config)
} catch (e) {
if (e instanceof BLEConnectionError) {
// 扫描超时、建连失败、设备不在范围内
console.error('BLE 连接失败', e.message, e.cause)
} else if (e instanceof BLECommunicationError) {
// 写特征失败
console.error('BLE 通信失败', e.message)
}
}
| 错误类 | 触发场景 |
|---|---|
BLEConnectionError |
open() 失败(超时/建连失败)、协商 MTU 失败、发现特征失败 |
BLECommunicationError |
send() 写特征失败 |
内部连接流程(open() 详细步骤)
1. openBluetoothAdapter() — 初始化蓝牙适配器
2. BLEScanCoordinator.scan() — 扫描(若 matchByDeviceId 则跳过)
3. closeBLEConnection() — 先断开历史连接(防止状态残留)
4. createBLEConnection() — 建立 BLE 连接(超时 10s)
5. sleep(500ms) — 等待连接稳定
6. setBLEMTU(512) — 协商 MTU(Android 最大 512,iOS 最大 185)
7. getBLEDeviceServices() — 获取服务列表
8. getBLEDeviceCharacteristics() — 遍历所有服务,收集可写 + notify 特征
9. notifyBLECharacteristicValueChange() — 使能所有 notify 特征
10. onBLECharacteristicValueChange() — 注册数据接收监听
11. onBLEConnectionStateChange() — 注册意外断开监听
平台支持
| 平台 | 支持 |
|---|---|
| 微信小程序 | √ |
| 支付宝小程序 | √ |
| APP-PLUS(Android / iOS) | √ |
| H5 | × (小程序 BLE API 不可用) |
集成到 pro-device-core 框架
BLE 设备基类已内置于本包:js_sdk/pro-device-adp-ble/ble-device-base.ts(导出 BLEDeviceBase)。
项目机型直接 extends BLEDeviceBase,无需再在 src/devices/base 放一层包装。

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 109
赞赏 0
下载 12681473
赞赏 1956
赞赏
京公网安备:11010802035340号