Android平台BLE设备写入正常但无法读取问题求助
排查BLE特征读取返回false的问题
结合你提供的代码和操作流程,我帮你梳理几个最可能导致读取失败的原因,以及对应的解决办法:
1. BLE操作的串行执行限制(最可能的原因)
Android的BLE GATT客户端同一时间只能处理一个操作,你在写入操作刚发起就立刻调用读取,这时候写入操作还在队列中等待执行,读取请求会被直接拒绝,导致返回false。
注意:writeCharacteristic返回true只是表示操作被成功加入请求队列,并不代表写入已经完成。正确的做法是在写入完成的回调里再发起读取请求:
修改步骤:
- 在你的
BluetoothLeService中重写onCharacteristicWrite回调方法:
@Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); // 确认写入成功 if (status == BluetoothGatt.GATT_SUCCESS) { Log.w(TAG, "写入操作完成"); // 检查是不是目标特征,再发起读取 if (characteristic.getUuid().equals(SampleGattAttributes.UNKNOWN_CHARACTERISTIC)) { boolean readStatus = gatt.readCharacteristic(characteristic); Log.w(TAG, "读取请求发起状态:" + (readStatus ? "成功" : "失败")); } } }
- 去掉你在
displayGattServices中直接调用的readCharacteristic,只保留写入调用:
// 只保留写入操作 byte [] byte1= {0x01, 0x10}; reqChar.setValue(byte1); mBluetoothLeService.writeCharacteristic(reqChar); // 读取操作移到写入回调中执行
2. 特征对象引用异常
你用了private static final DeviceControlActivity holder1 = new DeviceControlActivity();来保存特征和服务引用,这是一个全新的Activity实例,不是当前正在运行的DeviceControlActivity,很可能导致reqService或者reqChar的引用无效(比如mBluetoothLeService在这个新实例中未初始化)。
解决办法:直接在当前Activity中使用已有的mBluetoothLeService和特征对象,不要用静态Activity实例传递:
// 去掉holder1相关代码,直接使用当前类的变量 private BluetoothGattCharacteristic reqChar; // 在displayGattServices中找到特征后 reqChar = gattCharacteristic; byte [] byte1= {0x01, 0x10}; reqChar.setValue(byte1); mBluetoothLeService.writeCharacteristic(reqChar);
3. 确认特征的READ属性是否真的存在
虽然你说目标特征具备READ属性,但建议在找到特征时打印属性值,确认实际包含PROPERTY_READ:
if(uuid.equals(SampleGattAttributes.UNKNOWN_CHARACTERISTIC)) { int properties = gattCharacteristic.getProperties(); Log.w(TAG, "特征属性:" + properties); Log.w(TAG, "是否包含READ属性:" + ((properties & BluetoothGattCharacteristic.PROPERTY_READ) != 0)); // 后续操作... }
如果打印结果显示不包含READ属性,那可能是UUID匹配错误(拿到了其他特征),或者设备端的特征配置有问题。
4. 检查GATT连接状态
在发起读取前,确认设备仍然处于连接状态:
BluetoothDevice device = mBluetoothGatt.getDevice(); int connectionState = mBluetoothGatt.getConnectionState(device); if(connectionState != BluetoothProfile.STATE_CONNECTED) { Log.w(TAG, "设备已断开连接"); return; }
按照上面的步骤逐一排查,应该能解决读取返回false的问题。
内容的提问来源于stack exchange,提问作者Prabhjit Thind
相关产品推荐
相关产品推荐

