更新记录
1.0.23(2026-10-30)
- 修复 advertisData 在部分情况下可能为空的问题
- 修复 serviceData 在部分情况下可能为空的问题
1.0.22(2026-10-17)
- 修复 蒸汽模式下页面路由变化会导致插件错误自动关闭释放资源的BUG
- 新增「蓝牙-低功耗外围设备(BLE Peripheral / GATT Server)」能力组,对齐微信小程序 BLEPeripheralServer 系列 API
- 新增「蓝牙-信标(Beacon)」能力组,对齐微信小程序 BEACON 系列 API
- 新增「蓝牙-SPP(经典蓝牙)」能力组,非标准API,小程序/UNIAPP官方不支持,但API风格习惯追随微信小程序
- 新增 setPluginConfig / getPluginConfig 接口,可配置本插件的特性
- 新增 getBLEDeviceServices / getBLEDeviceCharacteristics 自动重试,由 setPluginConfig 配置
1.0.21(2026-01-30)
- 添加了 setBluetoothEnable 接口用于编程式开关系统蓝牙(无感开关或者用户交互)
- 实现了鸿蒙next平台无需搜索直接连接设备的特性(开发参考 createBLEConnection 标注信息)
- 修复了鸿蒙next平台 startBluetoothDevicesDiscovery 接口传入 services 参数非128bit时会报错的问题
- 修复了鸿蒙next平台蓝牙关闭时 onBluetoothAdapterStateChange 接口多次回调的问题
平台兼容性
uni-app(5.04)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | - | × | × | √ | √ | 5.0 | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(5.04)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | √ | √ | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| √ | √ | √ | √ |
开源对接例程,持续更新
- 由于DCloud插件市场的示例项目功能无法管理版本和更新日志,因此使用gitee进行版本管理
- 工程内的
utils文件夹包含了一些对BLE开发很有帮助的封装库utils.uts【常用BLE开发工具】 内含比如ab2hex的替代品bytes2hex,可将蓝牙数据转换为hex字符串ble.uts【跨平台调用插件】 极大简化 UniappX 工程跨端引用本插件- 更多用法请阅览源代码 ......
插件与接口的特点
UniAPP工程种类兼容性多,系统平台兼容性强,API种类多
| UniAPP JS | UniAPP X |
|---|---|
| ✅ | ✅ |
| IOS系统 | Android系统 | 鸿蒙NEXT纯血系统 |
|---|---|---|
| ✅ | ✅ | ✅ |
IOS、Android、鸿蒙NEXT,三端都支持,基于UniAPP JS引擎版本的工程甚至可以通过本插件自带的 BLE.js 无缝对齐,部署为小程序工程
| BLE中央主机 | BLE外围设备 | 经典蓝牙SPP |
|---|---|---|
| ✅ | ✅ | ✅ |
最常用的三种蓝牙协议,本插件都支持,一个插件解决市场上其他插件三个才能解决的问题,降低开发负担,提高开发速度
接口对齐度与接口兼容性高
- 95%的WX与UniApp的BLE主机模式的接口兼容性,尽全力对齐表现,减少代码迁移的时间损耗和兼容性问题排查的时间损耗
- 支持Promise风格配合
async与await进行api调用,与WX的实现思路基本一致 【参考WX的实现文档】
选型开发维护全程无忧
- 完善的文档,细致的注意事项,可帮助开发者减少开发难度,提高开发效率,快速上线APP
- 稳定维护,本插件已有对接的APP在提供服务,从立项到维护不怕插件断更导致APP功能异常甚至缺失而无法解决只能另寻他法
创新接口解决关键痛点
- 跟随最新的WX的BLE接口的实现,且创新式添加API,UniApp没有的本插件有,WX没有的本插件也有
- 全新设计批量传输接口,解决传输速率和传输包之间的间隔长的痛点
- 完美解决传输OTA大包时外设固件UART超时中断过短(1.5s以下),而WX与UNIAPP的官方API分包发送间隔过长导致大概率失败的问题
- 有效提高传输速率,减少js层分包发送带来性能损耗
接口的已知问题
本插件某些接口只支持注册一个回调而Uniapp和WX支持注册多个
- 原因:某些接口提供的注册方法虽然可以注册多个,但是解注册方法只能是全部进行解注册,解注册和注册的过程极其容易留下暗坑,比如内存泄露,回调混乱,生命周期不符合需求
- 解决方案:开发者自行维护这些API的注册以及解注册,在需要的时候注册,在不需要的时候解注册。真正传给本插件库的只有一个注册的回调函数,通过此回调函数进行分发处理
- 可参考 不同的BLE第三方库导致的回调混乱
- 可参考 本插件的例程实现的回调维护机制
- 受影响的API:onBluetoothDeviceFound、onBluetoothAdapterStateChange、onBLECharacteristicValueChange。注意,一般仅在多设备下链接下有影响。
云打包报错
- 原因:HBuilderX 版本过低或者过高
- 解决方案:请使用合适的 HBuilderX 版本
- 目前本插件的开发和调试是 [HBuilderX 5.04 正式版本] 和 [HBuilderX 5.31 Alpha版本]
闪退问题一览
- UniappJS引擎,使用此插件时,参数不正确传入导致闪退
- 原因:UniappJS会自动序列化js变量到原生层,如果类型不匹配就会抛出异常导致闪退
- 解决方案:接口文档声明必须要传的参数,绝不可漏,否则有闪退的可能性,并且确保类型与文档的描述一致
- tips:理论上UniappX引擎的工程编译时会检查类型完整性,但是为了避免闪退,请确保参数正确传入
- IOS端扫描到的设备信息暂时无法提供
serviceData字段- 原因:闪退issues 1
- 解决方案:HBuilderX升级到4.23及以上可解决此问题,目前插件已加入此修复逻辑,在 HBuilderX版本 >= 4.23 时自动开放此字段
- IOS端首次编译运行或者点击重新运行进行调试,使用蓝牙后一段时间内崩溃
- 原因:闪退issues 2
- 临时方案:编译运行后,手动杀死app,从桌面图标重新进入可正常运行不闪退
- tips:此问题仅在本插件开发时被插件开发者频繁遇到,已确认不影响使用本插件的APP
- IOS端UniAppJS引擎的APP调用接口许久以后内存爆炸导致闪退
- 原因:闪退issues 3
- 临时方案:使用
BLE.js封装库在js引擎的app下调用接口,切勿直接调用UTS接口- 临时解决方案仅能解决带
options入参的接口的内存泄漏,各种onXXX回调注册接口执行多了还是会泄漏
- 临时解决方案仅能解决带
onXXX接口调用超过几千上万次才‘可能’导致发生崩溃,如果你的逻辑里面没有非常频繁的以ms级别调用此类接口则无需担心,在用户使用APP的周期内都是比较稳定的- tips:仅有js引擎且是在IOS下的工程受到影响,包括 UniAppx IOS js逻辑层、UniApp JS IOS
异步接口并行高频次调用可能存在一些兼容性问题
-
setBLEMTU 接口需要等待原生层回调通知结果,期间如果开发者并行调用多次此接口,则可能存在只回调一次 success 而后 onBLEMTUChange 多次回调的可能性。
-
在鸿蒙next上,设置MTU,设置使能通知,读特征,写特征,这几个接口,需要在执行完成后才能执行下一次,否则会报错
errMsg: "readBLECharacteristicValue:fail BussinessError 2900099: Operation failed"
是否考虑优化:考虑,但不优先考虑,请开发者规范调用异步接口,在success与fail与complete中进行下一步操作
某些接口注册回调会重复的问题
-
IOS由于swift的闭包函数无法被比较的特性,在直接调用插件实现的UTS层实现的原生接口函数无法识别是否是已经注册过的函数,某些可以注册多个监听回调的接口多次调用会导致重复注册
-
Android端由于UTS插件的编译器的BUG,导致UniAPP JS引擎的js回调每次传递到UTS层都会创建一个新的lambda去实现UTS层定义的callback
-
关注重复注册的问题:重复注册 issues
-
受影响的API:
onBLEConnectionStateChangeonBLEMTUChange
同样,因为无法识别唯一性,上述的接口也无法调用其对应的 offXXX 接口,传入同一个回调函数的变量,去移除指定的回调函数的注册,而只能传入为空的变量,去移除所有的注册记录
插件开发者已经通过一些窍门去解决重复注册的问题,查看下方的兼容性框图,了解你的工程上是否会遇到此问题 🔥
| 平台 | 引擎 | 调用方式 | 是否解决重复注册的问题 | 注释 |
|---|---|---|---|---|
| Android | UniAPP JS | BLE.js |
✅ | 绕过编译器隐式的桥接 |
| iOS | UniAPP JS | BLE.js |
✅ | 绕过编译器隐式的桥接 |
| 鸿蒙NEXT | UniAPP JS | BLE.js |
✅ | 不存在这个问题 |
| Android | UniAPP JS | UTS export的接口 | ❌ | |
| iOS | UniAPP JS | UTS export的接口 | ❌ | |
| 鸿蒙NEXT | UniAPP JS | UTS export的接口 | ✅ | 不存在这个问题 |
| Android | UniAPP X | UTS export的接口 | ✅ | 没有编译器隐式桥接的问题 |
| iOS | UniAPP X(js逻辑层) | BLE.js |
✅ | 绕过编译器隐式的桥接 |
| iOS | UniAPP X(swift逻辑层) | UTS export的接口 | ❌ | swift逻辑层官方未上线 |
| 鸿蒙NEXT | UniAPP X(ArkTS逻辑层) | UTS export的接口 | ✅ | 不存在这个问题 |
因为iOS端的uniapp x swift逻辑层暂未上线,因此你可以忽略此工程的问题,只需要关注以下事项:
- 如果你是 UniApp JS 引擎的工程,按照下方教程安装插件后导入
BLE.js直接使用,没有此问题 - 如果你是 UniApp X 引擎的工程
- 在Android端使用
import * as UTSBLE from '@/uni_modules/xl-uts-bluetooth';导入后,直接按照教程调用接口 - 在IOS端使用
import * as UTSBLE from '@/uni_modules/xl-uts-bluetooth/jssdk/BLE.js';导入后,直接按照教程调用接口 - 在鸿蒙NEXT端使用
import * as UTSBLE from '@/uni_modules/xl-uts-bluetooth';导入后,直接按照教程调用接口 - 注意:如果需要兼容多端,应当使用条件编译,详细用法请参考插件的示例工程
- 在Android端使用
接口的兼容性处理
-
蓝牙需要获取相关的权限(不获取就没法搜索或者连接到设备):
如何按需移除插件的权限(例如客户不需要 Beacon / 外围设备等能力) 跳转到文档
-
Android:
- 在android6.0及以上,android12以下(不包括12),需要在运行时申请 (定位权限)
- android.permission.ACCESS_FINE_LOCATION
- android.permission.ACCESS_COARSE_LOCATION
- android.permission.ACCESS_BACKGROUND_LOCATION
权限用途:用于搜索BLE设备,不授权则无法搜索到任何蓝牙设备 注:iBeacon 信标搜索(startBeaconDiscovery)同样依赖定位权限
- 在android12及以上会出现的权限,需要在运行时申请 (附近的设备权限)
- android.permission.BLUETOOTH_SCAN
- android.permission.BLUETOOTH_ADVERTISE
- android.permission.BLUETOOTH_CONNECT
权限用途:用于搜索,连接,管理蓝牙设备,不授权则无法操作任何蓝牙设备
- 在android6.0及以上,android12以下(不包括12),需要在运行时申请 (定位权限)
-
鸿蒙NEXT:
- 需要用到 ohos.permission.ACCESS_BLUETOOTH 权限
权限用途:用于搜索和连接蓝牙设备,禁止后会导致无法搜索和连接蓝牙。 注:iBeacon 信标搜索(startBeaconDiscovery)同样依赖此权限,本插件会在信标搜索前检查并按需发起授权申请,未授权时回调
11001(蓝牙服务不可用)。 - 可能需要用到 ohos.permission.PERSISTENT_BLUETOOTH_PEERS_MAC 权限
- 需要用到 ohos.permission.ACCESS_BLUETOOTH 权限
-
iOS:
- 需要用到 NSBluetoothAlwaysUsageDescription 权限
- 需要用到 NSBluetoothPeripheralUsageDescription 权限
权限用途:您的应用需要始终访问蓝牙设备,以便与其他蓝牙设备进行持续的通信和数据传输。
- iBeacon 信标搜索(startBeaconDiscovery)还需要定位权限(NSLocationWhenInUseUsageDescription / NSLocationAlwaysAndWhenInUseUsageDescription)
权限用途:CoreLocation 进行 Beacon Ranging 需要定位权限,用于发现附近的 iBeacon 信标并计算距离。 本插件在 startBeaconDiscovery 时会检查定位授权状态:未决定时发起申请并等待授权回调,授权后继续;被拒绝/受限时回调错误码
11002(位置服务不可用)。
为了尽可能正常使用本插件,以及减少代码复杂性,尽可能贴近wx和uniapp的官方api的用法。本插件在使用 openBluetoothAdapter 接口时会自动申请需要的权限,这可能会导致app上架失败(有些市场要求上架的app在申请权限之前要app自定义一个弹窗声明权限用途,请求用户赋予) 如果您的APP不考虑上架市场,则可以直接使用所有的API进行开发,但是如果您需要上架国内的应用市场,请务必按照市场的要求检查系统版本号并且弹窗声明权限信息 在弹窗声明和申请相关的权限时,可参考上述的“权限用途”描述
-
-
禁止用
errMsg判断接口的执行结果在进行插件开发时,开发者搜索了大量的用例,发现网络上的开发者们的用法真是千奇百怪,有些用户甚至使用errMsg判断是否调用接口成功, 比如下方链接指向的用法:第82行代码,理论上来讲这是不规范的, 正确用法应当是判断errCode,如果你是从老的wx小程序代码中迁移BLE调用逻辑到本插件,请务必检查代码中是否包此类使用errMsg进行判断的逻辑,有的话请更改为使用errCode,
- 注:在实际的迭代过程中,wx或者uniapp或者本插件的errMsg的格式都有可能会变,且本插件无法百分百知晓在出现错误时,各大厂商对于errMsg的格式的实现。
-
batchWriteBLECharacteristicValue 接口在传输的过程中,严禁再次并行调用 writeBLECharacteristicValue 和 batchWriteBLECharacteristicValue
此接口一旦开启传输,会占用指定的服务下的指定特征用于自动在原生层分包发送数据块,一般此接口用于发送完整的固件、或者较大的数据封包, 这些数据在传输的过程中,往往都需要保证连续性和完整性,因此也不应该在发送的过程中穿插其他的数据,而是在接口的success执行后,再去调用任何的写接口
注:如果看到以下的错误代码以及错误信息,则说明你的代码逻辑没处理好串行写的逻辑,此时你应当检查是否错误的并行调用写接口,或者是在不同的事件(比如setTimer、setInterval)中误调接口,或是async调用时没有await
{ "errSubject": "xl-uts-bluetooth", "errCode": 10008, "errMsg": "writeBLECharacteristicValue:fail characteristic handler is busy" } -
writeBLECharacteristicValue 接口并行调用且传入 writeType 还不相同的情况下,会导致顺序错乱 这是已知问题,且短时间内无法修复,可能也不会考虑修复。在正常的蓝牙开发过程中,蓝牙的写操作是一个异步的操作,且是一个可能会由于各种原因失败的异步操作, 在你设计程序之初,就应当考虑将异步操作进行串行化,同步化(async + await),根据上次的write的执行结果决定本次需要重试还是继续发送还是结束发送和通知客户。而不是对一个设计之初就是异步的api进行并行调用,并行调用的情况下,由于writeType在各个平台 的实现略有不同,因此各个平台展现出来的特性也是也是不一样的,所以失败+数据错乱的概率会大大增加。
- 注:在对一个指定的服务特征并行执行了多次写操作之后,在还未全部结束的情况下尝试执行 batchWriteBLECharacteristicValue 接口会直接报错busy,请勿混用写接口。
-
所有的操作传入的参数,没有特殊说明的情况下按照以下规范进行:
- 字符串类型请传入大写字符串,比如deviceId, serviceId, characteristicId
-
MTU相关的接口在双端的差异性
- 下方论据以蓝牙模块 XY-MBA32A 为例子
-
Android: 经测试,在不同的机型,Android版本,系统版本,三个大区别上,BLE的表现特征是不一致的,碎片化比较严重
-
设备:红米Note8Pro,系统版本为miui12.5.6.0稳定版,Android版本为11
- 特性:createBLEConnection 创建BLE链接后,不会触发 onBLEMTUChange ,
且如果 setBLEMTU 不为517,会返回错误
setBLEMTU:fail android ble status 4
- 特性:createBLEConnection 创建BLE链接后,不会触发 onBLEMTUChange ,
且如果 setBLEMTU 不为517,会返回错误
-
设备:红米k60pro上,系统版本为hyperos1.0.8.0.UMKCNXM,Android版本为14
- 特性:createBLEConnection 创建BLE链接后会紧接着触发 onBLEMTUChange 通知MTU更改(外设的固件请求更改的),因此 getBLEMTU 获取的MTU就是更改后的MTU
-
设备:三星S23ULTRA上,系统版本为OneUI6.1,Android版本为14
- 特性:createBLEConnection 创建BLE链接后并没有任何的MTU更改的回调,因此 getBLEMTU 只能获取到默认的23大小
- 如果希望 getBLEMTU 可以获取到更大的MTU,则需要在外设支持的情况下调用 setBLEMTU 进行MTU的设置,经测试,对 XY-MBA32A 模块调用 setBLEMTU(任意值) 会触发 onBLEMTUChange 更改为517
-
getBLEMTU 接口获取到的MTU需要减去3,看这个文档了解详情:MTU在Android端的注意事项
-
结论:
- 连接设备前:先注册
onBLEMTUChange, 因为可能连接成功后直接就协商好MTU了,如果你没提前监听的话,可能会导致措施MTU更改的消息通知 - 连接设备后:尝试一次
setBLEMTU,无论能不能设置为指定的MTU值,至少在外设支持更改的情况下,Android底层是会尝试设置到双方都支持的最大值的, 设置成功后就能触发onBLEMTUChange
- 连接设备前:先注册
-
- IOS: 系统底层有协商MTU的逻辑的,只是开发者没办法接触到,也就是说,如果开发者需要更改MTU,需要由外设端发起更改,也就是说可以把锅丢给硬件固件部门的同事了
- getBLEMTU 的底层是调用了
maximumWriteValueLength,在IOS的官方API中,是把write和writeNoResponse两种传输类型区分对待的,两者能传输的长度是不一样的,注意,此长度不需要减去3,也就是此长度已经减去包含 Op-Code 和 Attribute Handle 的长度 setBLEMTU由于系统原因,原生不支持此API,自然也就不支持onBLEMTUChange
- getBLEMTU 的底层是调用了
- 特别注意:插件开发者在使用
XY-MBA32A透传模块和JDY-31-LE透传模块进行测试时,发现这两款产品都有MTU相关的逻辑问题- 在
XY-MBA32A模块上,发现尽管MTU可以设置为更大的值(517),但是调用API时如果发送比较大的数组,会回调成功,但是模块的TX没有数据出现,经测试只能发送255以内的包大小 - 在
JDY-31-LE模块上,对其串口RX写大于等于MTU大小的数据包时,BLE总是回调20个字节一次的包大小,也就是说其串口端并没有根据新的MTU进行分包发送 - MTU在一些非规范实现的BLE透传模块上,有很大的问题,并不可信,因此切记先测试模块的MTU是否支持设置,以及设置完成后,传输 MTU - 3 大小的字节的包是否能正常收到
- 在
-
在进行读写特征值的操作之前至少调用一次
getBLEDeviceServices接口- 否则有可能导致某些系统平台上,在调用读写特征值、获取特征列表的接口时,一直报错
10004 no service 没有找到指定服务 - 推荐在设备连接成功后,调用一次此接口确保服务探索完毕
- 如果存在其他接口调用操作,请确保
设置MTU和获取服务和设置通知使能这几个接口不是并行调用,而是按照顺序依次调用的。
- 否则有可能导致某些系统平台上,在调用读写特征值、获取特征列表的接口时,一直报错
-
MAC地址兼容性须知
- 在鸿蒙NEXT上,MAC地址是虚拟的,虽然搜索到的设备列表里面的地址看起来不像是IOS那种UUID形式的,但是其实这个也不是真正的MAC地址,而是被系统重映射隐藏之后的了。
- 老版本备注:手机的蓝牙重新开关,或者APP重启之后,这个虚拟地址会变化,因此如果涉及到重新开关蓝牙的逻辑,请记得重新搜索设备。
- 新版本备注:本插件新版本会调用 access.addPersistentDeviceId 原生接口持久化映射地址,此举是实现不搜索直接连接的重要基础,但是还是需要搜索和连接一次以此固定设备地址!
- 在Android上,MAC地址就是设备实际的MAC地址,不会变化,可以实现内置指定MAC地址进行连接
- 在iOS上,MAC地址被重映射为随机的UUID,并且根据某些系统规律进行变化,不是固定的
温馨提示:设备的MAC地址最好是现场搜索现场使用,千万不要缓存到本地,因为下一次就不一定是这个了!
- 在鸿蒙NEXT上,MAC地址是虚拟的,虽然搜索到的设备列表里面的地址看起来不像是IOS那种UUID形式的,但是其实这个也不是真正的MAC地址,而是被系统重映射隐藏之后的了。
-
当服务或者特征的UUID重复出现时,如何在操作时区分同一UUID的不同实例
- 如果可以,设备固件开发时,尽量不要做成一样的UUID,不然很多小程序平台没办法兼容这种设计,最终为难的还是设备厂家自己
- 本着插件少更新,小更新,尽量减少大批量更新带来的不稳定的可能性的原则,暂不考虑支持相同UUID的服务
- 对于特征的UUID重复,开发者可在连接设备后,通过 getBLEDeviceCharacteristics 接口返回的
handle字段值去标记不同的实例,然后在调用操作接口的时候,设置到characteristicHandle字段中,就可以区分不同实例了 - 参考WX的解决方案的实现(此实现未公开): 跳转阅览
- 参考github的解决方案:跳转阅览
注意:目前只支持Android平台,且不要缓存 handle 值,因为此值会在不确定的条件下有所变化!尽量只在一次连接中去使用。
-
Android端 UniappX 有概率出现多线程并发冲突
- 异常类型:java.util.ConcurrentModificationException
- 原因:为了发送/接收的处理速度,插件没在数据接收的回调里头转交给UI线程去回调,而是直接在Android的GATT线程里回调了数据达到,此时如果你直接在数据接收的回调里更新了UI,或者有其他定时器也在更新这个变量,那么就有可能出现此异常
- 解决办法:在MIAN线程中进行UI更新,Android切换到UI线程的办法
- 这个确实是考虑不周,为了速度导致这个隐藏问题的存在,但是确实多套一层任务转交到不同线程的操作对速度影响蛮大的,插件开发者后期会想办法尽量保证速度的情况下,解决这个并发问题,到时候使用者就无需自己转交了。
接口的使用前提
-
安装此插件到你的工程中(如果你是在DCLOUD插件市场中,请点击右侧按钮 ‘试用’)
-
导入插件
-
(1) 导入js二次封装库(UniAppJS引擎项目推荐此方法)
import * as UTSBLE from '@/uni_modules/xl-uts-bluetooth/jssdk/BLE.js';- 适用于UniappJS引擎的 IOS & Android & 鸿蒙NEXT 项目
- 适用于UniappX引擎JS逻辑层的IOS项目
- 支持代码提示,且参数自动修正为UTS要求类型,避免闪退
- 支持Promise语法调用,异步api的success,fail,complete三个回调都不传则返回一个Promise对象
-
(2) 导入UTS插件原生支持库(不推荐,原因看下方事项)
import * as UTSBLE from '@/uni_modules/xl-uts-bluetooth';- 适用于Android端的 UniappX引擎 的项目
- 适用于鸿蒙NEXT端的 UniappX引擎 和 Uniapp引擎 的项目
- 不支持Promise语法调用
-
(3) 导入uts二次封装库(UniAppX引擎项目推荐此方法)
import * as UTSBLE from '@/utils/ble.uts';- 适用于IOS、Android、鸿蒙NEXT、三端的 UniappX引擎 的项目
- 不支持UniappX swift逻辑层的IOS项目(官方未上线swift逻辑层,但是我先备注说明)
- 支持Promise语法调用,异步api的success,fail,complete三个回调都不传则返回一个Promise对象
注:
ble.uts源码可在 开源示例项目 找到。 在下载ble.uts完成后,将其放入到你的工程中(注意,不要放入到任何的uni_modules文件夹内),如果工程根目录已有utils文件夹,则可以直接放入进去然后参考上述文章的导入语法 如果ble.uts的存放目录有任何的变动,导入时也请修正为正确的路径! -
导入插件的额外注意事项和参考备注:
- iOS端的 UniAppX引擎JS逻辑层 的项目,第1和2和3种方式都支持。但是建议用第1(无跨端需求)或者第3种(有跨端需求),可以解决很多的已知问题
- UniAppJS引擎的 Android & IOS工程 & 鸿蒙NEXT 支持第1、2两种形式导入。只是第2种导入没有代码提醒和Promise化的支持,且可能导致重复注册回调,且类型或者值错误有可能会导致闪退,不建议使用。建议使用
BLE.js也就是第1种 - UniAppX引擎的 Android工程 只支持第2、3种调用方式。最终都是编译为kotlin原生代码,没有JS运行环境,如果没有跨端需求可以用第2种调用方式
- UniAppX引擎的 鸿蒙NEXT工程,编译之后是ARKTS,只支持第2、3种调用方式。最终都是编译为ARKTS原生代码,没有JS运行环境
- UniAppX引擎的项目,如果需要兼容 Android & IOS & 鸿蒙NEXT 可使用第3种调用方式导入
ble.uts进行调用,其内部已自动条件编译
-
-
按照下方接口文档,调用接口
接口列表
如果遇到特性没有完全对齐的情况,可以酌情向插件开发者反馈,插件开发者会在接口下方标注,然后尽量抹除差异进行对齐
调用时请根据您的import方式进行调用,如果您的import是别名as方式,请使用别名进行调用,比如
UTSBLE.openBluetoothAdapter(参数)
非标接口(本插件特有或非跨端)
提醒您,使用以下接口可能会导致跨端/跨平台移植难度增加,请和产品经理开会讨论之后再决定是否使用
可使用条件编译或者平台判断逻辑进行跨端处理
- setBluetoothEnable
- setPluginConfig
- 修改插件配置,目前支持
enableLog、autoDiscoverySvrCharTimeout两个配置项 enableLog默认为false(不打印内部日志);设置为true后,插件会在各 API 调用、事件回调(设备发现、连接状态、MTU 变化、适配器状态等)的关键节点通过console.log打印信息,便于调试autoDiscoverySvrCharTimeout默认为0(不自动重试);配置为非0时(单位 ms),getBLEDeviceServices/getBLEDeviceCharacteristics会自动重试:当获取到的服务或特征列表长度为 0(或调用失败)时,立即发起下一轮请求,直到列表长度不为 0、或累计耗时超过此超时时间(成功与超时均走 success 回调,由调用方判断列表长度)- 以上配置对整个插件全局生效(跟随 APP 生命周期),配置一次即可,无需每次调用 API 都配置
- 日志统一格式:
[xl-uts-bluetooth][tag] ...
- 修改插件配置,目前支持
- getPluginConfig
- 获取当前插件配置,返回
{ enableLog, autoDiscoverySvrCharTimeout, errCode, errMsg } - 与
setPluginConfig对称,用于查询当前生效的配置
- 获取当前插件配置,返回
- batchWriteBLECharacteristicValue
- 可用
writeBLECharacteristicValue接口模拟(速度无提升)
- 可用
蓝牙-通用
- stopBluetoothDevicesDiscovery
- startBluetoothDevicesDiscovery
- openBluetoothAdapter
- onBluetoothDeviceFound
- 只能注册一个,多设备链接可能受影响,解决方案参考顶上的已知问题
- onBluetoothAdapterStateChange
- 只能注册一个,多设备链接可能受影响,解决方案参考顶上的已知问题
- offBluetoothDeviceFound
- offBluetoothAdapterStateChange
- makeBluetoothPair
- 微信官方描述为仅安卓支持,本插件在鸿蒙NEXT上也提供了实现用于对齐使用场景
- 通常情况下(需要指定 pin 码或者密码时)系统会接管配对流程,直接调用 createBLEConnection 即可;该接口只应当在开发者不想让用户手动输入 pin 码且真机验证确认可以正常生效情况下用
- iOS端不支持此接口,调用后会打印不支持的消息并回调失败(错误码
10007)
- isBluetoothDevicePaired
- 微信官方描述为仅安卓支持,本插件在鸿蒙NEXT上也提供了实现用于对齐使用场景
- iOS端不支持此接口,调用后会打印不支持的消息并回调失败(错误码
10007)
- getBluetoothDevices
- getConnectedBluetoothDevices
- 在IOS上一定需要指定主服务的UUID,才能检索到已连接的BLE设备
- 在ANDROID上一定要将主服务的UUID列表设置为空列表,才能检索到已连接的BLE设备
- 在鸿蒙NEXT上同ANDROID一致,描述同上。(注:功能已实现,但是HBX的云打包机的SDK版本太旧,会编译失败,因此鸿蒙NEXT暂时不开放此接口)
- 局限性:无法获得搜索才能获得的信息,比如广播数据,RSSI之类的,且一般来说是用于GATT特性的设备的,并且本插件开发者对其他协议比如音频相关的了解甚少,不建议使用此接口查询诸如此类的设备。
- getBluetoothAdapterState
- 在蓝牙未授权或是未开启的状态下,本接口走success回调上报
available为false
- 在蓝牙未授权或是未开启的状态下,本接口走success回调上报
- closeBluetoothAdapter
- 关闭适配器会导致所有的设备都断开连接,所有设置的回调都被清除,非app退出请勿关闭适配器
蓝牙-低功耗中心设备(BLE Central / GATT Client)
- writeBLECharacteristicValue
- Android端一次性写入过多的数据,某些高级别的系统版本上可能会返回
fail writeCharacteristic return false,请根据MTU进行分包发送 - 在IOS和鸿蒙NEXT上,一次性传入过多的数据进行写入,可能会出现回调成功但是实际上数据并未达到/完全达到设备端的问题,请根据MTU进行分包发送
- Android端一次性写入过多的数据,某些高级别的系统版本上可能会返回
- setBLEMTU
- readBLECharacteristicValue
- onBLEMTUChange
- onBLEConnectionStateChange
- onBLECharacteristicValueChange
- 只能注册一个,多设备链接可能受影响,解决方案参考顶上的已知问题
- iOS端返回的是无符号(0到255)的number[],Android端返回的是有符号(-128到127)的number[],可通过 toUnsignedBytes() 函数转换为无符号
- offBLEMTUChange
- offBLEConnectionStateChange
- offBLECharacteristicValueChange
- notifyBLECharacteristicValueChange
- type的默认值为 ‘indication’。iOS上不受type影响,会同时打开 ‘indication’ 和 ‘notification’
- getBLEMTU
- getBLEDeviceRSSI
- getBLEDeviceServices
- ⚠️ IOS端在设备连接后,会自动发起服务探索,ANDROID和鸿蒙NEXT有兼容性问题所以没有加入这个逻辑,因此需要你调用此接口确认探索到你需要操作的服务之后,再操作读写特征。
- 连接成功后立刻调用可能会报错
10004,请自行实现在指定的时间内反复重试的逻辑 - 新版本插件支持自动重试,可看 setPluginConfig 接口
- getBLEDeviceCharacteristics
- 连接成功后立刻调用可能会报错
10005,请自行实现在指定的时间内反复重试的逻辑 - 新版本插件支持自动重试,可看 setPluginConfig 接口
- 连接成功后立刻调用可能会报错
- createBLEConnection
- 就算对同一个
deviceId的设备并行调用此接口也只会创建一个BLE链接,且开发者并行调用了几次就会回调几次 - 不搜索直接创建链接的特性:
- iOS平台的
deviceId是变动的,因此不支持此特性 - Android端
deviceId就是固定的mac地址,可直接使用此特性(微信小程序也支持此特性) - 鸿蒙NEXT需搜索一次设备,得到需要连接的设备地址,调用此接口后该地址从此固定,除非卸载APP,此后支持直接连接(需要申请额外权限,请参考权限章节)
非跨端特性,勿滥用,否则会给跨端需求带来烦恼。
- iOS平台的
- 就算对同一个
- closeBLEConnection
蓝牙-低功耗外围设备(BLE Peripheral / GATT Server)
对齐微信小程序 蓝牙-低功耗外围设备 能力组,让本机作为 BLE 从机(GATT 服务端)被其他主机连接、读写与订阅。
说明:对齐微信,
createBLEPeripheralServer成功回调返回{ server, peripheralId },其中server是 BLEPeripheralServer 的实例,可直接调用server.addService(...)等方法(uni-app x 直调 UTS 时可使用实例方法)。 在 uni-app JS 引擎下,原生 server 实例无法跨到 JS 层,jssdk/BLE.js会用peripheralId在 JS 侧重建一个门面类,用法保持一致。
- onBLEPeripheralConnectionStateChanged
- 顶层全局 API(不与某个 server 实例绑定),回调
{ deviceId, serverId, peripheralId, connected },用serverId区分是哪个实例
- 顶层全局 API(不与某个 server 实例绑定),回调
- offBLEPeripheralConnectionStateChanged
- createBLEPeripheralServer
- 创建本地外围设备服务端,成功回调返回
{ server, peripheralId };可创建多个(Android/鸿蒙支持多实例,iOS 受系统限制同时仅支持一个广播)
- 创建本地外围设备服务端,成功回调返回
- BLEPeripheralServer.addService
- 添加服务,参数
{ service },service结构对齐微信(uuid/characteristics,特征含properties/permission/value/descriptors);notify/indicate 特征未提供 descriptors 时会自动补 CCCD
- 添加服务,参数
- BLEPeripheralServer.removeService
- BLEPeripheralServer.startAdvertising
- 开始广播,参数
{ advertiseRequest, powerLevel };advertiseRequest支持connectable/deviceName/serviceUuids/manufacturerData/beacon - 平台差异:
manufacturerData仅 Android/鸿蒙支持(iOS 系统限制无法定制);beacon目前 Android/鸿蒙支持形式有限,iOS 不支持;iOS 同时只能发起一个广播
- 开始广播,参数
- BLEPeripheralServer.stopAdvertising
- BLEPeripheralServer.writeCharacteristicValue
- 参数
{ serviceId, characteristicId, value, needNotify, callbackId? };收到onCharacteristicReadRequest/onCharacteristicWriteRequest后应立刻调用本接口回包(携带对应callbackId),否则主机不会收到响应
- 参数
- BLEPeripheralServer.close
- 关闭服务端并回收该实例占用的原生资源,建议使用完毕后调用以避免内存泄漏
- BLEPeripheralServer.onCharacteristicReadRequest / offCharacteristicReadRequest
- BLEPeripheralServer.onCharacteristicWriteRequest / offCharacteristicWriteRequest
- BLEPeripheralServer.onCharacteristicSubscribed / offCharacteristicSubscribed
- BLEPeripheralServer.onCharacteristicUnsubscribed / offCharacteristicUnsubscribed
蓝牙-信标(Beacon / iBeacon)
对齐微信小程序 Beacon 能力组,用于发现附近满足指定 UUID 的 iBeacon / Beacon 设备,并解析出 major / minor / proximity / accuracy / rssi。该能力与「中央设备扫描(startBluetoothDevicesDiscovery)」相互独立。
对齐微信:Beacon 相关接口可直接使用,无需调用
openBluetoothAdapter初始化蓝牙适配器模块;但由于 Beacon 可用于定位,需要系统位置权限才能使用(权限见上方「接口的兼容性处理」章节)。 说明:Beacon 接口与普通蓝牙接口共用「关闭适配器」时的资源回收——若你调用了closeBluetoothAdapter,正在进行的信标搜索会被一并停止并释放资源。平台实现差异:
- Android:
BluetoothLeScanner按 Apple 厂商 ID(0x004C)过滤 + 解析 iBeacon 广播([0x02,0x15]+ 16B UUID + major/minor 大端 + txPower);5.0 以下走startLeScan。proximity固定为 0,accuracy用txPower/rssi估算。- iOS:
CoreLocation的CLBeaconRegion+startRangingBeacons(in:),proximity(unknown=0/十分近=1/比较近=2/远=3)与accuracy(proximity 为 0 时取 -1)由系统提供。- 鸿蒙 NEXT:
ble.startBLEScan+ble.on('BLEDeviceFind')手工解析广播 AD 结构。proximity固定为 0,accuracy估算方式同 Android。- 错误码对齐微信:
11000unsupport /11001蓝牙服务不可用 /11002位置服务不可用 /11003已经开始搜索 /11004还未开始搜索 /11005系统错误 /11006参数不正确。⚠️ Android 端扫不到 iBeacon 的常见原因(重要)
BLUETOOTH_SCAN不能声明neverForLocation:Android 官方文档明确 —— 一旦声明android:usesPermissionFlags="neverForLocation",系统会在扫描结果中过滤掉部分 BLE beacon(如 iBeacon),导致startBeaconDiscovery扫不到设备(而 nRF Connect 等未声明该 flag 的 App 却能扫到)。本插件为支持信标搜索已在插件自身的AndroidManifest.xml中去掉了该 flag。- 若你的工程通过 manifest.json「强制移除权限」等方式重新声明或覆盖了
BLUETOOTH_SCAN,请务必不要再带上neverForLocation。- 信标扫描需要定位权限:Android 6.0 及以上均需授予定位权限(
ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION);Android 12+ 还需BLUETOOTH_SCAN。本插件会在startBeaconDiscovery时自动申请,未授权回调11002。- 权限变更后需卸载重装:
neverForLocation等权限 flag 的变更仅在全新安装时生效,覆盖安装可能不生效。若你此前装过带该 flag 的版本,请卸载后重新安装再测试。- 排查顺序:①确认广播确为 Apple 厂商数据(
0xFF,公司 ID0x004C,数据以02 15开头);②确认uuids与信标 UUID 完全一致(本插件按 UUID 精确过滤);③确认系统定位服务已开启;④确认未被「扫描过于频繁」限流。
- startBeaconDiscovery
- 开始搜索 Beacon 设备,
uuids(Beacon 广播 UUID 列表)必填 ignoreBluetoothAvailable(是否校验蓝牙开关)仅在 iOS 下有效- Android 下会先申请定位/附近设备权限,未授权回调
11002
- 开始搜索 Beacon 设备,
- stopBeaconDiscovery
- getBeacons
- 返回
{ beacons: BeaconInfo[], errMsg }
- 返回
- onBeaconUpdate / offBeaconUpdate
- 监听 Beacon 设备更新事件,回调
{ beacons }(当前搜寻到的所有 Beacon 设备列表)。对齐微信,仅能注册一个监听
- 监听 Beacon 设备更新事件,回调
- onBeaconServiceChange / offBeaconServiceChange
- 监听 Beacon 服务状态变化事件,回调
{ available, discovering }。对齐微信,仅能注册一个监听
- 监听 Beacon 服务状态变化事件,回调
- BeaconInfo
- Beacon 设备信息实例
蓝牙-经典蓝牙 SPP(Serial Port Profile / RFCOMM)
经典蓝牙串口通信能力组,基于 RFCOMM 提供「客户端主动连接」与「服务端监听等待连入」两种角色,微信与官方 uni-app 均无对应 API,属本插件扩展能力,但接口风格习惯上追随微信小程序的命名与回调约定。
支持平台:Android、鸿蒙 NEXT;iOS 平台不提供经典蓝牙 SPP 能力,相关接口统一回调错误码
10020。 设计说明:所有 SPP API 均为展平的顶层函数且只收一个 options 对象,连接句柄socketId/ 服务端句柄serverId均放在 options 内;客户端与服务端建立连接后产出的都是socketId,共用同一套收发 / 关闭 / 事件体系。 数据接收为推送式:已建立的连接收到数据后通过onSPPReceiveData事件上报。常见注意事项:
- 地址来源:SPP 只接受经典蓝牙(BR/EDR)设备地址,请使用
startBluetoothDevicesDiscovery({ scanClassic: true })上报的classicDevices,或getBondBluetoothDevices获取的已配对设备;不要用 BLE 扫描得到的deviceId。- UUID 一致性:客户端与(对端设备支持的)服务端 UUID 必须完全一致,否则连接失败(
10021)。- 配对:部分设备/机型需先完成系统配对(bonded)才能建立 RFCOMM 连接。
- 单回调限制:
onSPPReceiveData/onSPPConnectionStateChange/onSPPClientCreateByServer均仅支持一个监听,多页面切换请在onShow中重新注册。- 资源回收:
closeBluetoothAdapter会自动释放所有 SPP 连接与服务端;也可通过closeSPPClient/closeSPPServer精确关闭。

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