常见失败原因:权限未开、系统蓝牙关闭或被占用;iOS需配置NSBluetoothAlwaysUsageDescription,Android需动态申请定位权限;H5不支持,须用uni.canIUse判断;搜索不到设备需检查外设广播模式及startDiscovery参数;连接后读特征值前须依次调用onBLEConnectionStateChange、getConnectedBluetoothDevices、getBLEDeviceServices、getBLEDeviceCharacteristics;通信不稳定需处理状态机、加错误码判断、控制写入节奏并实现心跳保活与指数退避重连。

uni-app 调用 uni.openBluetoothAdapter 失败的常见原因
不是权限没开,就是系统级蓝牙未启用或被其他 App 占用。iOS 上还必须在 info.plist 里加 NSBluetoothAlwaysUsageDescription,否则直接静默失败;Android 则需动态申请 android.permission.ACCESS_FINE_LOCATION(即使你只连 BLE,系统也强制要定位权限)。
实操建议:
- 调用
uni.openBluetoothAdapter前,先用uni.getSystemInfoSync().platform区分平台,iOS 做描述文案兜底,Android 主动uni.authorize定位权限 - 失败回调里打印
err.errMsg,重点看是否含bluetooth not available(系统蓝牙关了)或unauthorized(权限拒绝) - H5 端不支持蓝牙,
uni.getConnectedBluetoothDevices等 API 会直接报错,务必用uni.canIUse('openBluetoothAdapter')做运行时判断
搜索不到设备?uni.startBluetoothDevicesDiscovery 启动后没回调
BLE 扫描不是“启动就出结果”,它依赖底层广播 + 主动轮询,且 Android/iOS 行为差异极大:iOS 默认只扫已配对设备(除非传 allowDuplicatesKey: true),Android 则可能因省电策略中途停扫。
实操建议:
- 确保外设处于可发现模式(广播包中
ADV_IND类型、非连接态),用 nRF Connect 等工具先验证能否被手机原生系统识别 - 调用
uni.startBluetoothDevicesDiscovery时,显式传{ services: [], allowDuplicatesKey: true },避免 iOS 漏设备 - 监听
uni.onBluetoothDeviceFound必须在 start 之后、且不能延迟注册——有些安卓厂商(如小米)会丢掉首条扫描结果,建议 start 后立即绑定事件
连接成功却读不到特征值?uni.getConnectedBluetoothDevices 返回空数组
这是最隐蔽的坑:uni-app 的 connect 是异步建立链路,但设备真正“连上”和“服务发现完成”是两件事。很多开发者以为 uni.createBLEConnection 回调一来就能读,其实此时服务树还没加载,uni.getConnectedBluetoothDevices 自然查不到。
实操建议:
- 必须等
uni.onBLEConnectionStateChange触发且connected === true后,再调用uni.getConnectedBluetoothDevices - 紧接着立刻调用
uni.getBLEDeviceServices,拿到 serviceId 后,再调uni.getBLEDeviceCharacteristics—— 缺少任一环,uni.readBLECharacteristicValue都会报service not found - 某些设备(尤其带 OTA 功能的)会在连接后自动断开重连,导致 characteristic 缓存失效,建议每次读写前都重新 get 一次 characteristics
Android 上频繁断连、iOS 写入超时?BLE 通信稳定性怎么控
uni-app 封装层把 native 调用压成 JS Promise,但 BLE 底层是事件驱动+状态机。写入超时(write timeout)、连接中断(connection lost)往往不是代码写错了,而是没处理好状态跃迁和重试边界。
实操建议:
- 所有 BLE 操作(read/write/notify)都加
try/catch,错误码优先匹配10007(连接已断)、10008(写入超时),而不是只看fail回调 - notify 开启后,必须监听
uni.onBLECharacteristicValueChange,且该事件可能触发多次——别在第一次就resolvePromise,容易漏数据 - 避免高频写入:Android 上连续
write间隔低于 20ms 极易丢包,iOS 对 write-with-response 更敏感,建议加setTimeout控制节奏
BLE 不是 HTTP,没有“请求-响应”的确定性;设备端固件行为、手机蓝牙芯片、系统后台策略都会干扰。真要稳,得在连接态做心跳保活,断连后按指数退避重连,这些逻辑没法靠 uni-app 一层封装兜住。

















