Android应用无法读取Raspberry Pi蓝牙CPU温度特征问题排查
问题修复方案
核心问题分析
- 属性判断逻辑错误:蓝牙特征的
properties是按位组合的数值,你看到的18对应PROPERTY_READ(2) | PROPERTY_NOTIFY(16),直接用== PROPERTY_READ会匹配失败,导致读操作无法执行。 - 通知配置不完整:仅调用
setCharacteristicNotification(true)无法真正开启通知,必须配置对应的客户端特征配置描述符(CCCD)才能触发onCharacteristicChanged回调。 - 父类方法参数传错:
onServicesDiscovered中调用父类方法时传入了未初始化的gatt变量,可能干扰后续GATT流程。
代码修复步骤
1. 修正特征属性判断逻辑
将原代码中的精确相等判断改为按位与判断,检查特征是否包含读属性:
// 原错误代码 if (it.properties == BluetoothGattCharacteristic.PROPERTY_READ) // 修复后代码 if ((it.properties and BluetoothGattCharacteristic.PROPERTY_READ) != 0)
2. 完整配置通知开关
在开启通知后,添加CCCD的配置代码,确保通知能正常触发:
val cccdUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") val descriptor = it.getDescriptor(cccdUuid) descriptor?.let { desc -> desc.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE discoveredGatt.writeDescriptor(desc) }
3. 修正父类方法调用参数
onServicesDiscovered中调用父类方法时,传入正确的discoveredGatt参数:
override fun onServicesDiscovered(discoveredGatt: BluetoothGatt?, status: Int) { super.onServicesDiscovered(discoveredGatt, status) // 替换原错误的gatt参数 // ... 其余代码 }
4. 完整修复后的onServicesDiscovered方法
override fun onServicesDiscovered(discoveredGatt: BluetoothGatt?, status: Int) { super.onServicesDiscovered(discoveredGatt, status) if(status == BluetoothGatt.GATT_SUCCESS){ gatt = discoveredGatt Log.d(TAG,"Services discovered") val service = discoveredGatt?.getService(UUID.fromString("00000001-710e-4a5b-8d75-3e5b444bc3cf")) if(service!=null){ Log.d(TAG,"Service found") service.characteristics.forEach { Log.d(TAG,"Characteristic: ${it.uuid}") Log.d(TAG,"Characteristic permission: ${it.permissions}") Log.d(TAG,"Characteristic properties: ${it.properties}") // 处理读属性 if ((it.properties and BluetoothGattCharacteristic.PROPERTY_READ) != 0){ Log.d(TAG,"Characteristic is readable") discoveredGatt.readCharacteristic(it) } // 处理通知属性 if ((it.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) { discoveredGatt.setCharacteristicNotification(it, true) val cccdUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") val descriptor = it.getDescriptor(cccdUuid) descriptor?.let { desc -> desc.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE discoveredGatt.writeDescriptor(desc) } } } } } }
额外注意事项
- Android 12及以上版本,需确保应用已申请并获得
BLUETOOTH_CONNECT、BLUETOOTH_SCAN运行时权限。 - 确认树莓端cputemp服务正常运行,特征UUID与代码中使用的完全一致。
内容的提问来源于stack exchange,提问作者Bot
相关产品推荐
相关产品推荐

