You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter重复写入同一BLE特征报ERROR_GATT_WRITE_REQUEST_BUSY错误排查

蓝牙BLE设备写入特征异常排查(Flutter Blue Plus)

问题现象

  • 首次点击isLinked按钮向目标特征写入命令成功
  • 点击LinkRing按钮向同一特征写入不同命令时触发错误,核心错误提示为ERROR_GATT_WRITE_REQUEST_BUSY和UNKNOWN_GATT_ERROR (133),最终导致连接断开

核心错误日志

E/flutter (9263): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(setNotifyValue, gatt.writeDescriptor() returned 201: ERROR_GATT_WRITE_REQUEST_BUSY, null, null)

完整错误日志:

I/flutter (19243): Write error: FlutterBluePlusException | writeCharacteristic | fbp-code: 1 | Timed out after 15s
I/flutter (19243): Write successful[36, 83, 32, 57, 102, 48, 101, 50, 107, 32, 116, 114, 117, 101]
I/flutter (19243): [FBP] <writeCharacteristic> args: {remote_id: BC:02:6E:AF:D9:5B, service_uuid: b56c04ea-6cba-4dd4-83b9-7f3056a1bac5, secondary_service_uuid: null, characteristic_uuid: 6ae5deca-d2d0-4e13-a662-ad16e9a78dde, write_type: 0, allow_long_write: 0, value: 24532039663065326b2074727565}
D/[FBP-Android](19243): [FBP] onMethodCall: writeCharacteristic
I/flutter (19243): Write error: PlatformException(writeCharacteristic, gatt.writeCharacteristic() returned 201 : ERROR_GATT_WRITE_REQUEST_BUSY, null, null)
D/BluetoothGatt(19243): onConnectionUpdated() - Device=BC:02:6E:AF:D9:5B interval=48 latency=30 timeout=600 status=0
E/[FBP-Android](19243): [FBP] onCharacteristicWrite:
E/[FBP-Android](19243): [FBP]   chr: 6ae5deca-d2d0-4e13-a662-ad16e9a78dde
E/[FBP-Android](19243): [FBP]   status: UNKNOWN_GATT_ERROR (133) (133)
D/BluetoothGatt(19243): onClientConnectionState() - status=22 clientIf=13 device=BC:02:6E:AF:D9:5B
D/[FBP-Android](19243): [FBP] onConnectionStateChange:disconnected
D/[FBP-Android](19243): [FBP]   status: CONNECTION_TERMINATED_BY_LOCAL_HOST
D/BluetoothGatt(19243): close()
D/BluetoothGatt(19243): unregisterApp() - mClientIf=13
I/flutter (19243): [FBP] [[ OnCharacteristicWritten ]] result: {error_string: UNKNOWN_GATT_ERROR (133), service_uuid: b56c04ea-6cba-4dd4-83b9-7f3056a1bac5, success: 0, remote_id: BC:02:6E:AF:D9:5B, error_code: 133, characteristic_uuid: 6ae5deca-d2d0-4e13-a662-ad16e9a78dde, value: 24532039663065326b2074727565}
I/flutter (19243): [FBP] [[ OnConnectionStateChanged ]] result: {disconnect_reason_code: 22, disconnect_reason_string: CONNECTION_TERMINATED_BY_LOCAL_HOST, remote_id: BC:02:6E:AF:D9:5B, connection_state: 0}

相关代码

按钮触发代码

ElevatedButton(
  onPressed: () {
    print("isWatchLinkedTo");
    for (var service in _services) {
      if (service.uuid == targetSensorServiceUUID) {
        for (var characteristic in service.characteristics) {
          if (characteristic.uuid ==
              targetSensorCharacteristicUUID) {
            sensorcharacteristic = characteristic;

            String result = "\$S userId false";
            sensorcharacteristic!.setNotifyValue(true);
            startListening();
            _writeCharacteristic(sensorcharacteristic!, result);
          }
        }
        break;
      }
    }
  },
  child: Text("isLinked")),
ElevatedButton(
  onPressed: () {
    print("linkRingTo");
    for (var service in _services) {
      if (service.uuid == targetSensorServiceUUID) {
        for (var characteristic in service.characteristics) {
          if (characteristic.uuid ==
              targetSensorCharacteristicUUID) {
            sensorcharacteristic = characteristic;
            String result = "\$S userId true";
            _writeCharacteristic(sensorcharacteristic!, result);
          }
        }
        break;
      }
    }
  },
  child: Text("LinkRing")),

写入与队列逻辑代码

Future<void> _writeCharacteristic(
    BluetoothCharacteristic characteristic, String value) async {
  _enqueueOperation(() async {
    if (_isWriting) return;

    _isWriting = true;
    print("Write successful${Uint8List.fromList(utf8.encode(value))}");
    try {
      await characteristic.write(Uint8List.fromList(utf8.encode(value)));
      print("Write successful${Uint8List.fromList(utf8.encode(value))}");
    } catch (e) {
      print("Write error: $e");
    } finally {
      _isWriting = false;
    }
  });
}

Future<void> startListening() async {
  subscription = sensorcharacteristic?.onValueReceived.listen((value) {
    print("PairCheck New : $value");
  });
}

void _enqueueOperation(Future Function() operation) {
  _operationQueue.add(operation);
  _processQueue();
}

Future<void> _processQueue() async {
  if (_isProcessingQueue) return;
  _isProcessingQueue = true;

  while (_operationQueue.isNotEmpty) {
    final operation = _operationQueue.removeAt(0);
    await operation();
  }

  _isProcessingQueue = false;
}

问题分析

  1. 队列逻辑冗余:_isWriting标记与队列的串行处理逻辑重复,若标记未正确重置会导致后续任务直接跳过;同时BLE设备未完成前一次写入ACK时,新的写入请求会触发GATT栈繁忙错误。
  2. 重复设置Notify:isLinked按钮每次点击都会调用setNotifyValue(true),重复触发CCCD描述符写入操作,与后续特征写入请求冲突,加剧GATT栈负载。
  3. 设备响应延迟:同一特征连续写入时,设备未及时处理完前一次请求,导致GATT栈拒绝新请求,最终触发未知错误并断开连接。

解决方案

1. 优化队列逻辑,移除冗余标记

利用队列的串行特性保证单任务执行,移除_isWriting标记:

Future<void> _writeCharacteristic(
    BluetoothCharacteristic characteristic, String value) async {
  _enqueueOperation(() async {
    final bytes = Uint8List.fromList(utf8.encode(value));
    print("Writing value: $bytes");
    try {
      await characteristic.write(bytes);
      print("Write successful: $bytes");
    } catch (e) {
      print("Write error: $e");
    }
  });
}

2. 避免重复开启Notify

添加状态标记,仅在未开启通知时执行setNotifyValue:

// 类内添加状态标记
bool _isNotifyEnabled = false;

// 修改isLinked按钮逻辑
if (!_isNotifyEnabled) {
  await sensorcharacteristic!.setNotifyValue(true);
  _isNotifyEnabled = true;
  startListening();
}

3. 增加写入间隔(可选)

针对处理速度较慢的设备,在队列任务间添加短暂延迟:

Future<void> _processQueue() async {
  if (_isProcessingQueue) return;
  _isProcessingQueue = true;

  while (_operationQueue.isNotEmpty) {
    final operation = _operationQueue.removeAt(0);
    await operation();
    await Future.delayed(Duration(milliseconds: 200)); // 根据设备调整延迟时长
  }

  _isProcessingQueue = false;
}

4. 调整写入类型(可选)

若设备支持,使用无响应写入类型避免ACK等待阻塞:

await characteristic.write(bytes, writeType: WriteType.withoutResponse);

内容的提问来源于stack exchange,提问作者avinash Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:17:02