返回

如何解决蓝牙连接中写入特征值时的 ERROR_GATT_WRITE_REQUEST_BUSY 错误?

Android

蓝牙连接中写入特征值时解决 ERROR_GATT_WRITE_REQUEST_BUSY 错误

问题概要

在启用蓝牙通知后写入特征值时,遇到恼人的 ERROR_GATT_WRITE_REQUEST_BUSY 错误?别担心,你并不孤单!让我们深入探讨原因和解决方法。

错误原因

当应用程序在 GATT 操作进行中时试图写入特征值时,就会触发此错误。在启用通知时,我们需要写入特征值符 (CCCD) 来在设备上打开通知流。然而,如果我们在 onServicesDiscovered() 回调中执行此写入,它将与 GATT 操作相冲突,从而导致错误。

解决方法

1. 延迟 CCCD 写入

为了解决这个问题,我们只需将 CCCD 写入操作移出 onServicesDiscovered() 回调。我们可以使用 postDelayed() 函数来延迟写入,例如:

gatt?.postDelayed({
    val cccd = rrepCharacteristic?.getDescriptor(CCCD_UUID)
    if (cccd != null) {
        gatt?.writeDescriptor(cccd, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
    }
}, DELAY_TIME)

2. 设置延迟时间

DELAY_TIME 是延迟写入 CCCD 的时间(以毫秒为单位)。建议将其设置为 500-1000 毫秒,以确保 GATT 操作已完成。

3. 处理写入结果

延迟写入 CCCD 后,我们可以处理写入结果。在 onDescriptorWrite() 回调中,检查写入是否成功。

启用通知

通过延迟 CCCD 写入,我们可以在 GATT 操作完成后启用通知。此时,我们可以正常写入特征值,并且应用程序将开始接收通知。

避免在 GATT 操作期间写入

为了防止此错误,请务必避免在 GATT 操作进行中时写入特征值。这包括在 onServicesDiscovered()、onCharacteristicChanged() 和其他 GATT 回调中写入操作。

常见问题解答

1. 为什么会出现 ERROR_GATT_WRITE_REQUEST_BUSY 错误?

它是由应用程序在 GATT 操作期间尝试写入特征值时触发的。

2. 如何解决此错误?

延迟 CCCD 写入操作,并避免在 GATT 操作期间写入特征值。

3. 延迟 CCCD 写入有什么作用?

它确保在 GATT 操作完成后再写入 CCCD,从而避免冲突。

4. 如何处理写入结果?

在 onDescriptorWrite() 回调中检查写入是否成功。

5. 如何避免此错误?

不要在 GATT 操作进行中写入特征值。