Android BLE开发中gatt.writeDescriptor()一直返回false问题求助
gatt.writeDescriptor返回false和你协程的写法本身没有直接关联,大概率是Android BLE API本身的使用限制导致的,常见原因如下:
- 串行操作冲突
Android BLE的所有GATT操作(读特征、写特征、读描述符、写描述符、开通知等)必须串行执行,同一时间只能有一个未完成的GATT操作。如果调用写描述符时,上一个GATT操作还没收到对应的回调,就会直接返回false。你需要维护一个GATT操作队列,所有操作排队依次执行,前一个操作收到回调后再执行下一个。 - 线程调用错误
BluetoothGatt的所有公开方法必须在主线程(或者拥有Looper的线程)调用,如果你的suspend函数运行在Dispatchers.IO这类子线程调度器下,调用GATT方法会直接返回false。你需要切换到Dispatchers.Main调度器执行所有GATT相关操作。 - 权限缺失
Android 12及以上版本必须提前申请BLUETOOTH_CONNECT运行时权限,未授权的情况下调用任何GATT操作都会返回false。 - 参数或状态错误
- 确认你调用该方法的时机是在
BluetoothGattCallback.onServicesDiscovered回调成功之后,未完成服务发现时操作特征/描述符都会失败。 - 确认目标Characteristic的属性包含
PROPERTY_NOTIFY或PROPERTY_INDICATE,不支持通知/指示的特征无法配置对应描述符。 - 确认你传入的
descValue是正确的配置值:开普通通知传BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE,开指示传BluetoothGattDescriptor.ENABLE_INDICATION_VALUE,值错误也会导致调用失败。 - 确认你用的
UUID_CLIENT_CHAR_CONFIG值正确,就是你提到的00002902-0000-1000-8000-00805f9b34fb,UUID拼写错误会导致获取到空的描述符或者操作失败。
- 确认你调用该方法的时机是在
另外你当前的协程实现有个小缺陷:当gatt.writeDescriptor(desc)返回false时,你已经将对应的key存入了descWriteCont,但抛出异常后没有移除该key,会导致后续调用同一个特征的通知配置时直接抛出last not finished yet的异常,需要在resumeWithException之前先把对应key从descWriteCont中移除。
内容的提问来源于stack exchange,提问作者CTABUYO
相关产品推荐
相关产品推荐

