uni.getbledeviceservices必须在成功连接设备后调用,否则报错errcode=10001;其返回的服务列表需通过serviceid获取特征值,characteristicid须直接使用硬件返回的原始值,不可格式化或硬编码。

uni.getBLEDeviceServices 必须在连接后调用
没连上设备就调 uni.getBLEDeviceServices,一定会失败,错误码是 errCode=10001(设备未连接)。这个 API 不是“查设备有什么服务”,而是“查已连接设备暴露了哪些服务”。所以流程上必须严格遵循:先 uni.createBLEConnection 成功,再立刻调它。
常见错误现象:
- 控制台报错
getBLEDeviceServices:fail not connected - success 回调没触发,但也没报错(其实是被静默忽略,尤其在 iOS 上)
- 返回的
services数组为空,即使硬件明确支持多个服务
实操建议:
- 把
uni.getBLEDeviceServices放在uni.createBLEConnection的success回调里,不要用异步延迟或事件总线中转 - 检查返回的
services是否含isPrimary: true,优先取主服务(多数设备只暴露一个主服务) - 别依赖
name或description字段识别服务——这些字段在 Android/iOS 上基本为空或不可靠,只认uuid
uni.getBLEDeviceCharacteristics 返回的 characteristicId 是硬件给的,不是你拼的
拿到 serviceId 后调 uni.getBLEDeviceCharacteristics,返回的每个 characteristic 对象里,characteristicId 就是你要传给后续读写/通知的值。它不是你根据 serviceId 拼出来的,也不是标准 UUID(比如 00002a19-0000-1000-8000-00805f9b34fb),而是设备实际广播或 GATT 表里声明的那个原始字符串——可能全小写、带大写、缺横线,甚至看起来像乱码。
容易踩的坑:
- 手动补全 UUID 格式(比如加横线、转大小写),导致
notifyBLECharacteristicValueChange报errCode=10002(无效 characteristicId) - 误以为“可 notify 的特征值只有一个”,其实一个 service 下可能有多个 notify 特征(比如心率值 + 心率状态),得遍历
properties.notify判断 - 在 iOS 上,某些设备要求先
read一次特征值才能启用notify,否则state: true会静默失败
实操建议:
- 打印整个
res.characteristics数组,逐个看characteristicId和properties,别只盯着第一个 - 启用 notify 前,先确认该 characteristic 的
properties.notify === true,而不是靠 UUID 猜 - 安卓和 iOS 对 UUID 大小写敏感性不同:iOS 通常不敏感,安卓部分机型(尤其旧版)严格区分,建议直接用返回的原值,不做任何格式化
serviceId 和 characteristicId 必须由硬件方提供,不能猜也不能硬编码
虽然你可以用 uni.getBLEDeviceServices 和 uni.getBLEDeviceCharacteristics 扫出来,但前提是硬件已按规范正确配置 GATT 表。如果扫不到、扫出来是空、或者扫到的 UUID 和文档对不上,问题大概率在硬件端,不是前端代码错了。
为什么不能靠“标准 UUID”硬编码?
- 蓝牙 SIG 定义的标准 UUID(如电池服务
0000180f-0000-1000-8000-00805f9b34fb)只是参考,厂商可以自定义;很多国产传感器根本不用标准 UUID - 同一款硬件,固件版本升级后可能改 serviceId / characteristicId,硬编码会导致新固件无法通信
- 扫描结果受系统蓝牙栈限制:Android 低版本、部分定制 ROM 可能过滤掉非标准 service,导致扫不出来
实操建议:
- 调试阶段务必向硬件工程师索要明确的
serviceId和支持notify的characteristicId,写死在配置里比动态扫更稳 - 如果必须动态发现,加一层 fallback:扫不到时尝试用已知的硬件 UUID 直接调
getBLEDeviceCharacteristics,避免卡死 - 在 HBuilderX 真机运行时,打开「调试器 → Bluetooth」面板,能直观看到扫描到的服务和特征结构,比 console.log 更可靠
Android 上 getBLEDeviceCharacteristics 可能被系统限频或中断
在部分 Android 机型(尤其是 MIUI、EMUI、ColorOS),连续快速调用 uni.getBLEDeviceCharacteristics(比如遍历多个 service)容易触发系统保护,导致后续调用直接失败或超时,错误信息类似 errCode=10006(连接超时)或无响应。
这不是 uni-app 的 bug,是系统蓝牙栈的节流策略。iOS 相对稳定,但也不建议高频轮询。
解决方法很实际:
- 每次调
getBLEDeviceCharacteristics后,用setTimeout延迟 300–500ms 再调下一个,别堆在 for 循环里 - 如果只关心某一个特定 service,不要先
getBLEDeviceServices全扫一遍再过滤,而是直接用已知的serviceId调用getBLEDeviceCharacteristics - 在
fail回调里加重试逻辑(最多 2 次),但重试前必须等至少 200ms,否则越重试越卡
真正麻烦的点在于:这个限制没有统一规则,不同品牌、不同系统版本表现不一,只能靠真机测+降频保稳。别指望一次代码适配所有安卓机。











