Android BLE onCharacteristicChanged回调未触发问题求助
Android BLE客户端onCharacteristicChanged回调不触发问题排查与解决
问题概述
开发Android BLE客户端,已成功扫描连接ESP32回声服务器,订阅通知的流程执行成功(描述符写入返回GATT_SUCCESS),服务器日志显示已发送通知,但客户端onCharacteristicChanged始终未触发。Xamarin客户端同流程可正常工作,排除服务器端问题。
核心问题分析
1. 回调方法版本兼容问题
你重写的onCharacteristicChanged是Android 13(API 33)新增的重载方法,签名为:
override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray )
若测试设备系统版本低于API 33,系统会调用旧版本的回调方法(无value参数),但你的代码未实现该版本,导致回调无法触发。
2. 特征实例引用不一致
在onMtuChanged中,你通过BLE_Object.gatt获取服务和特征,而非回调参数传入的gatt实例,可能导致引用的Gatt对象与当前连接的实例不一致,无法接收通知。
解决方案
步骤1:同时实现两个版本的onCharacteristicChanged
兼容所有Android版本,添加旧版本回调方法:
override fun onCharacteristicChanged(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?) { super.onCharacteristicChanged(gatt, characteristic) characteristic?.value?.let { Log.d("TAG", "收到通知(兼容版):${String(it)}") } } override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray ) { super.onCharacteristicChanged(gatt, characteristic, value) Log.d("TAG", "收到通知(API33+):${String(value)}") }
步骤2:修正特征获取的Gatt实例
在onMtuChanged中使用回调传入的gatt参数获取服务和特征,避免引用错误:
override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) { Log.d("TAG", "onMtuChanged") super.onMtuChanged(gatt, mtu, status) if (gatt == null) return // 使用当前连接的gatt实例获取服务和特征 mService = gatt.getService(SERVICE_UUID) mOut = mService?.getCharacteristic(OUT_UUID) mIn = mService?.getCharacteristic(IN_UUID) // 后续订阅逻辑不变... }
额外检查点
- 确认已申请对应Android版本的BLE权限:Android 12+需
BLUETOOTH_CONNECT、BLUETOOTH_SCAN;低版本需BLUETOOTH、ACCESS_COARSE_LOCATION - 验证ESP32发送通知的特征UUID与客户端订阅的UUID完全匹配(日志中已确认一致,可跳过)
内容的提问来源于stack exchange,提问作者Orbian
相关产品推荐
相关产品推荐

