Wear OS调用device.createBond()时立即出现‘无法连接’提示的问题
Wear OS 连接Nonin 3150 BLE血氧仪问题排查与解决方案
问题详情
我正在开发一款Wear OS安卓应用,目标SDK 32(最低30),运行在三星Galaxy Watch 4上,尝试连接Nonin 3150 BLE血氧仪。根据设备集成指南,需要先连接、配对、绑定再加密连接,步骤比Android官方蓝牙指南多,但目前两种尝试方法都失败:
- 直接连接GATT:执行
bluetoothAdapter.getRemoteDevice(address)后立即调用device.connectGatt(),会连续收到两次onConnectionStateChange回调:第一次是CONNECTED且状态码GATT_SUCCESS,第二次是DISCONNECTED且状态码GATT_SUCCESS。在CONNECTED状态时调用gatt.discoverServices()无任何反应。 - 先绑定再连接:调用
device.createBond()后,计划在BroadcastReceiver回调中触发device.connectGatt(),但点击绑定按钮后立即弹出“Couldn't Connect”的Toast,仅收到BluetoothDevice.BOND_BONDING回调,后续无任何进展。
补充背景:
- 应用基于Jetpack Compose开发,所有蓝牙逻辑都写在绑定到ViewModel的
Service中。 - 设备集成指南显示采用Just Works配对方式,尝试调用
device.setPin("0000".toByteArray(Charsets.UTF_8))无效果。
解决方案建议
调整GATT连接参数
调用connectGatt()时将autoConnect设为true,部分BLE设备需要系统自动触发连接来启动配对流程,而非主动发起的即时连接。示例代码:device.connectGatt(context, true, gattCallback)修正绑定流程逻辑
- 不要直接调用
createBond(),先发起一次短暂的GATT连接(无需调用discoverServices),触发设备的配对请求后再处理绑定广播。 - 监听
BluetoothDevice.ACTION_BOND_STATE_CHANGED广播时,覆盖全状态处理:- 收到
BOND_BONDED时再发起GATT连接; - 收到
BOND_NONE或BOND_FAILED时,检查设备是否被蓝牙设置忽略,重新触发绑定。
- 收到
- 不要直接调用
Service中启用专用蓝牙线程
蓝牙GATT操作不能在主线程执行,即使是Service也默认用主线程,容易导致操作阻塞。在Service中创建专用线程处理蓝牙逻辑:private val bluetoothThread = HandlerThread("BluetoothThread").apply { start() } private val bluetoothHandler = Handler(bluetoothThread.looper) // 所有GATT操作通过handler.post切换到专用线程 bluetoothHandler.post { device.connectGatt(context, true, gattCallback) }确认Wear OS蓝牙权限
SDK 30+需在Manifest中添加BLUETOOTH_CONNECT权限,并在运行时请求。Wear OS权限请求和手机端一致,确保应用在前台时已获取该权限,后台运行时权限受限会导致连接失败。移除手动Pin设置
Nonin 3150采用Just Works配对,无需手动调用setPin(),该操作会干扰系统自动配对流程,直接移除即可。深入调试日志
- 在
onConnectionStateChange中打印设备地址、状态码和完整错误信息,即使显示GATT_SUCCESS,设备也可能因配对未完成主动断开。 - 在Logcat中过滤
BluetoothGatt、BluetoothDevice标签,查看系统层面的蓝牙日志,定位断开的具体原因。
- 在
内容的提问来源于stack exchange,提问作者Tyler Moroso
相关产品推荐
相关产品推荐

