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

Flutter蓝牙接收ESP32数据遇FormatException:输入意外结束

解决Flutter蓝牙接收JSON时的FormatException问题

问题原因

蓝牙通信的输入流是流式传输,并非每次回调都会完整接收一个JSON数组:

  • 可能出现分片接收(一次只收到JSON的一部分)
  • 可能收到空数据包、换行符或额外空白字符
  • 你当前的代码直接将每次收到的字节转成字符串就解析,遇到不完整的JSON片段或空内容时,就会触发Unexpected end of input错误

解决方案

1. 缓存数据+按分隔符提取完整JSON

在ESP32端给每个JSON数据包末尾添加固定分隔符(比如\n),Flutter端缓存所有接收的数据,每次按分隔符分割出完整的JSON片段再解析。

修改后的Flutter代码:

String _dataBuffer = '';
final String _delimiter = '\n'; // 和ESP32端保持一致

void _startListening() {
  _connection!.input!.listen((Uint8List data) {
    String newData = utf8.decode(data);
    _dataBuffer += newData;

    // 循环处理所有完整的JSON片段
    while (_dataBuffer.contains(_delimiter)) {
      int delimiterPos = _dataBuffer.indexOf(_delimiter);
      String completeJson = _dataBuffer.substring(0, delimiterPos).trim();
      // 更新缓存,移除已处理的内容
      _dataBuffer = _dataBuffer.substring(delimiterPos + 1);

      if (completeJson.isNotEmpty) {
        try {
          List<dynamic> sensorData = json.decode(completeJson);
          debugPrint('解析结果: $completeJson');
          setState(() {
            _sensorData = sensorData;
          });
        } catch (e) {
          debugPrint('解析失败: $e');
        }
      }
    }
  });
}

2. ESP32端配合修改

确保ESP32发送JSON时末尾添加分隔符,以Arduino为例:

// 生成JSON字符串后,用println发送(自动追加换行符)
Serial.println(jsonString);

3. 关键优化点

  • 缓存机制:避免分片数据导致的解析失败
  • 错误捕获:用try-catch包裹JSON解析,防止未处理异常崩溃
  • 空数据过滤:跳过空字符串,避免解析空内容触发错误

补充说明

你控制台打印的完整JSON格式是正确的,报错是因为某次回调收到了不完整的片段(比如单独的换行符),直接解析就会抛出异常。流式处理是串口/蓝牙通信的标准方案,能保证数据的完整性。

内容的提问来源于stack exchange,提问作者Kavindu Wijesekara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:05:34