更新记录
1.0.0(2026-10-21)
首个发布版本。Android / iOS / 鸿蒙 NEXT 三端同构的 BLE 插件。 核心能力
- 蓝牙适配器管理:openAdapter / closeAdapter / getAdapterState,实时状态事件(adapterState、authorization)
- BLE 扫描:startScan / stopScan,支持按服务 UUID、设备名、名称包含/前缀、RSSI 下限、指定地址多条件过滤,支持 durationMs 自动停止与重复上报
- 设备查询:getScannedDevices(扫描缓存)/ getBondedDevices(系统配对)/ getConnectedDevices(系统已连接)/ getKnownDevices(免扫描重连)
- 连接管理:createConnection(连接超时保护、自动服务发现、自动重连)/ disconnect / closeConnection / isConnected
- 服务与特征:getServices / discoverServices,读写 / 订阅(notify)/ 描述符读写,统一大写 HEX 字符串数据格式
- 参数调节:requestMtu、readRssi、requestConnectionPriority(Android)、setPreferredPhy
- 扩展能力:外设模式(BLE 广播 + GATT Server,Android/iOS)、经典蓝牙 SPP(Android)、打开系统蓝牙设置页
- 统一事件总线 onBluetoothEvent / offBluetoothEvent,覆盖适配器状态、设备发现、连接状态、服务发现、特征回传、扫描启停等全部事件
1.0.0(2026-10-21)
首个发布版本。Android / iOS / 鸿蒙 NEXT 三端同构的 BLE 插件。
核心能力
- 蓝牙适配器管理:openAdapter / closeAdapter / getAdapterState,实时状态事件(adapterState、authorization)
- BLE 扫描:startScan / stopScan,支持按服务 UUID、设备名、名称包含/前缀、RSSI 下限、指定地址多条件过滤,支持 durationMs 自动停止与重复上报
- 设备查询:getScannedDevices(扫描缓存)/ getBondedDevices(系统配对)/ getConnectedDevices(系统已连接)/ getKnownDevices(免扫描重连)
- 连接管理:createConnection(连接超时保护、自动服务发现、自动重连)/ disconnect / closeConnection / isConnected
- 服务与特征:getServices / discoverServices,读写 / 订阅(notify)/ 描述符读写,统一大写 HEX 字符串数据格式
- 参数调节:requestMtu、readRssi、requestConnectionPriority(Android)、setPreferredPhy
- 扩展能力:外设模式(BLE 广播 + GATT Server,Android/iOS)、经典蓝牙 SPP(Android)、打开系统蓝牙设置页
- 统一事件总线 onBluetoothEvent / offBluetoothEvent,覆盖适配器状态、设备发现、连接状态、服务发现、特征回传、扫描启停等全部事件
平台兼容性
uni-app(5.13)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | - | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uts-bluetooth
uni-app x 蓝牙插件:BLE 中心设备 + 外设模式 + 经典蓝牙,Android / iOS 接口与事件完全一致。
安装
把整个 uni_modules/uts-bluetooth 目录拷贝到你的 uni-app x 项目的 uni_modules/ 下即可(uni_modules 机制会自动生效)。
uni_modules/uts-bluetooth/
├── package.json
├── README.md
└── utssdk/
├── interface.uts 类型定义
├── app-android/
│ ├── index.uts UTS 薄封装
│ ├── AndroidManifest.xml 权限(已含 neverForLocation)
│ └── *.kt 原生实现(BleKitBridge + 核心库)
└── app-ios/
├── index.uts
├── Info.plist 权限
└── *.swift 原生实现(BleKitBridge + 核心库)
原生代码与仓库根目录 android/、ios/ 保持同步,改动请两边一起改(或直接改插件目录里的那份)。
快速上手
import {
openAdapter, startScan, stopScan, createConnection, closeConnection,
getServices, readCharacteristic, writeCharacteristic,
notifyCharacteristicChanged, requestMtu, onBluetoothEvent
} from '@/uni_modules/uts-bluetooth'
// 1. 注册全局事件(建议只注册一次)
onBluetoothEvent((name, data) => {
console.log(name, data)
})
// 2. 打开蓝牙
openAdapter({})
// 3. 扫描(15 秒自动停)
startScan({ durationMs: 15000, services: ['FFE0'], rssiMin: -90 })
// 4. 在 deviceFound 事件里拿到 deviceId 后连接
createConnection({ deviceId, mtu: 512, connectionPriority: 1, autoReconnect: true })
// 5. servicesDiscovered 事件后读写
notifyCharacteristicChanged({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE1', enable: true })
writeCharacteristic({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE2', value: 'AABB01', writeType: 2 })
readCharacteristic({ deviceId, serviceUuid: 'FFE0', characteristicUuid: 'FFE3' })
// 6. 用完必须关闭,Android 连接数有上限(约 7 个)
closeConnection({ deviceId })
API
| 方法 | 关键参数 | 说明 |
|---|---|---|
openAdapter / closeAdapter |
- | iOS 只能返回当前状态,不能直接开关 |
getAdapterState |
- | success.res.state:on/off/... ,iOS 额外返回 authorization |
startScan |
services[] / deviceName / namePrefix / nameContains / rssiMin / allowDuplicates / durationMs / scanMode / phy |
Android 走硬件过滤,iOS 走软件过滤 |
stopScan |
- | |
getScannedDevices / getBondedDevices |
- | 返回 res.devices[];getBondedDevices 仅 Android |
getConnectedDevices |
services[](仅 iOS 生效) |
查系统层面已连接的 BLE 设备,返回 res.devices[];iOS 必须传 services,Android 返回本机已连接的 GATT 设备 |
getKnownDevices |
deviceIds[] |
按 deviceId 查已知设备(Android=MAC / iOS=peripheral UUID),免扫描直接 createConnection |
createConnection |
deviceId / mtu / timeoutMs / autoReconnect / connectionPriority / phy / transport / autoConnect / refreshCache |
|
closeConnection / disconnect / isConnected |
deviceId |
|
getServices |
deviceId |
返回 res.services[](缓存,不触发发现) |
discoverServices |
deviceId / uuids[] |
|
readCharacteristic / writeCharacteristic |
deviceId / serviceUuid / characteristicUuid / value |
writeType:2 带响应、1 无响应、4 签名写 |
readDescriptor / writeDescriptor |
+ descriptorUuid |
|
notifyCharacteristicChanged |
enable |
|
requestMtu / readRssi |
iOS 的 requestMtu 只返回当前值 |
|
setPreferredPhy |
txPhy / rxPhy(1=LE 1M / 2=LE 2M / 3=LE Coded) |
仅 Android 生效,iOS 返回 fail |
openBluetoothSettings |
- | 打开系统蓝牙设置页,仅 Android |
requestConnectionPriority / setPreferredPhy / refreshGattCache |
仅 Android,iOS 返回 fail | |
createBond / removeBond |
仅 Android | |
外设 startAdvertising / stopAdvertising / addService / removeService / removeAllServices / notifySubscribers / respondToRequest |
手机被别的设备连接 | |
经典蓝牙 startClassicDiscovery / connectSpp / sppWrite / closeSpp |
仅 Android(iOS 只有 MFi) | |
onBluetoothEvent / offBluetoothEvent / destroy |
事件(onBluetoothEvent)
| 事件名 | 主要字段 |
|---|---|
adapterState |
state |
scanStart / scanStop / scanFailed |
reason / code+message |
deviceFound |
device: { deviceId, address, name, rssi, deviceType, bondState, advertisement } |
connectionStateChanged |
deviceId, state(connecting/connected/disconnected), status, statusName |
servicesDiscovered |
deviceId, services[](含 characteristics、descriptors) |
characteristicRead / characteristicWrite / characteristicChanged |
deviceId, serviceUuid, characteristicUuid, value, status |
descriptorRead / descriptorWrite |
+ descriptorUuid |
notificationStateChanged |
enabled, status |
mtuChanged / rssi / phyUpdate |
mtu / rssi / txPhy,rxPhy |
bondStateChanged |
bondState(仅 Android) |
外设:advertiseStart / centralConnectionChanged / serviceAdded / readRequest / writeRequest / notificationSent |
|
经典:classicDiscoveryStart / sppData / sppError |
|
error |
code, message, deviceId? |
两端差异(写代码时要注意)
- deviceId:Android = MAC;iOS = peripheral 的 UUID 字符串(没有 MAC,重装 App 会变)
- MTU:Android 可请求;iOS 系统自动协商,只能读(
maximumWriteValueLength + 3) - iOS 没有:连接优先级、PHY、刷新 GATT 缓存、主动配对、经典蓝牙 SPP
- 数据格式:所有字节用大写 HEX 字符串(
"AABB01")传输 - 权限:插件已声明;Android 12+ 运行时权限仍需宿主 App 触发系统授权弹窗(首次调用时系统自动弹,若被拒需引导去设置)
- iOS
openAdapter不是"打开蓝牙开关":只是创建CBCentralManager并触发系统授权。刚创建时state=unknown属正常(delegate 是异步回调),本次实现已把.unknown视为成功,真正的结果看adapterState事件(state+authorization合并上报)或getAdapterState。失败时errMsg形如openAdapter:fail state=unauthorized authorization=denied。 - iOS 设备名:纯广播设备
CBPeripheral.name常为nil,插件已回退到广播包CBAdvertisementDataLocalNameKey;两者都没有时会返回空name,此时用deviceId/ 广播serviceUuids区分设备。 - iOS 启动卡在
state=unknown:说明最终 IPA 里没有NSBluetoothAlwaysUsageDescription, 系统不会弹授权框。uni-app 工程请在 manifest.json → app-plus → distribute → ios → privacyDescription 里声明(插件自带的app-ios/Info.plist只在 uni-app x 工程保证合并),改完需重新打自定义基座/云打包。 - iOS 扫描:蓝牙未就绪时
startScan返回 fail(errMsg带state=),同时发scanFailed事件, 不会再出现"startScan:ok 但扫不到设备"的假成功。
鸿蒙 NEXT(app-harmony)支持
基于 @kit.ConnectivityKit(access + ble,API 12+)实现,核心 BLE 能力与 Android/iOS 同构:
| 能力 | 鸿蒙状态 |
|---|---|
| 扫描(软件过滤:services/name/contains/prefix/rssiMin/address) | ✅ |
| 连接(超时保护)/ 断开 / 自动重连(最多 N 次) | ✅ |
服务发现(连接后自动发现,servicesDiscovered 事件) |
✅ |
| 读 / 写 / 订阅(notify)/ 描述符读写 | ✅ |
MTU(setBLEMtuSize,自动收敛到 22~517) |
✅ |
| 经典蓝牙 SPP、外设模式(GATT Server/广播) | ❌ 运行 fail(鸿蒙为另一套 API) |
| readRssi / PHY / 连接优先级 / refreshGattCache | ❌ 运行 fail |
getBondedDevices |
恒空(三方无系统配对列表查询) |
getConnectedDevices / getKnownDevices |
从本插件扫描/连接缓存里查(无系统级查询) |
鸿蒙端要点
- deviceId = 蓝牙 MAC 地址(与 Android 一致),服务端
device_id可直接复用。 - 广播 serviceUuids 为完整大写 UUID(如
0000CEB2-0000-1000-8000-00805F9B34FB), 配套页面用shortUuid()比对,短码/完整/大小写都能兼容,globalData.iosDeviceId无需改。 - 特征属性缺失:鸿蒙
GattService不提供 characteristics 的properties, 事件/getServices 里properties为空数组——按属性找 notify/write 特征的逻辑需自行兜底(如取第一个特征)。 - 权限(必须):宿主鸿蒙工程
module.json5需声明ohos.permission.ACCESS_BLUETOOTH(BLE 扫描建议再加APPROXIMATE_LOCATION/LOCATION)。openAdapter会尝试requestPermissionsFromUser主动申请;未声明时系统拒绝,扫描报 201。 - UUID 传参:系统 API 只接受完整格式,插件内部自动把短码(如
CEB2)扩展为0000CEB2-0000-1000-8000-00805F9B34FB,页面层传短码或完整串均可。 - 工程要求:HBuilderX 4.25+,标准 uni-app 需先生成/使用鸿蒙工程跑自定义基座。
已知注意
- Android 用完连接必须
closeConnection,否则连接数满后所有连接返回 133 - Android 12+ 的
BLUETOOTH_SCAN必须保留neverForLocation,否则扫描返回 0 个设备 - 首次云编译若报 UTS 类型相关错误,把报错发我,我按 UTS 语法修正(原生层已编译验证通过)

收藏人数:
购买普通授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 14
赞赏 0
下载 12702267
赞赏 1957
赞赏
京公网安备:11010802035340号