uni-app蓝牙开发必须真机运行,iOS需配置NSBluetoothAlwaysUsageDescription及蓝牙后台模式,Android 12+需动态申请bluetoothScan/connect权限,且API调用须严格串行、分平台处理,否则90%失败。

必须真机运行,模拟器完全不可用;iOS 和 Android 权限路径、API 调用时序、错误码含义完全不同,不区分平台硬写一套逻辑,90% 会卡死在 uni.openBluetoothAdapter 或搜不到设备。
uni.openBluetoothAdapter 失败的四个硬门槛
这不是代码写错了,而是系统级条件没满足:
- iOS 必须在
manifest.json的app-plus → permissions中勾选「蓝牙」,并填写NSBluetoothAlwaysUsageDescription字段;Xcode 打包后还需手动开启 Background Modes → Bluetooth Central - Android 12+(API 31+)必须动态申请两个独立权限:
scope.bluetoothScan和scope.bluetoothConnect,不能只调一次uni.authorize - Android API 30 及以下仍需
scope.location(系统把扫描归为定位行为),且华为/小米等厂商可能静默关闭扫描,得弹窗引导用户手动打开 - 调用前必须确认系统蓝牙已开启:
uni.getBluetoothAdapterState({ success: res => res.available === true }),否则uni.openBluetoothAdapter会静默失败或返回errCode=10001
startBluetoothDevicesDiscovery 搜不到设备的典型原因
设备本身没问题,大概率是参数或监听时机错位:
- 没等
uni.openBluetoothAdapter的success回调执行完,就直接调uni.startBluetoothDevicesDiscovery→ 报errCode=10000 -
uni.onBluetoothDeviceFound必须在startBluetoothDevicesDiscovery之前注册,且不能用箭头函数(this绑定失效会导致监听丢失);它只对本次 discovery 有效,重启扫描就得重绑 - 没传
services: []参数:很多 BLE 设备广播时不带 service UUID,iOS/iOS 15+ 默认过滤掉,必须显式传空数组才可见
createBLEConnection 后读不到数据?流程断在中间了
连接成功 ≠ 可通信。BLE 是严格的状态机,跳过任意一步都会报 errCode=10006:
- 必须监听
uni.onBLEConnectionStateChange,确认回调中connected: true后再走下一步 - 调
uni.getBLEDeviceServices获取服务列表,注意筛选isPrimary: true的主服务(比如你的温湿度计协议里是0xFFE0) - 再用该服务的
uuid调uni.getBLEDeviceCharacteristics,重点看properties.notify或properties.write是否为true(大小写敏感) - 启用通知必须用
uni.notifyBLECharacteristicValueChange({ state: true, serviceId, characteristicId }),漏掉serviceId或拼错characteristicId(如把0xFFE2写成ffe2)都会失败
写入指令和解析返回值的关键细节
控制硬件本质就是往特定 characteristic 发送字节序列,但格式极易出错:
- 发送前必须用
Buffer.from([...])或new Uint8Array([...])构造二进制数据,不能直接传字符串或十进制数组(比如指令[0x01, 0x02]传成"0102"就会失败) - 读取通知数据时,
uni.onBLECharacteristicValueChange回调里的value是 base64 字符串,必须用uni.getBase64Data或atob()+Uint8Array解码才能拿到原始字节 - 某些设备要求写入后等待固定延迟(如 200ms)再读,否则返回空或旧值;也有设备要求连续写两次指令才生效——这些都得查硬件协议文档,不能靠猜
最常被忽略的一点:所有蓝牙 API 调用必须严格串行,不能并发触发;on 类监听器(如 onBLEConnectionStateChange)必须在对应操作前注册,且每次新连接都要重新绑定——很多人以为注册一次全局有效,结果换设备就收不到通知。











