Flutter蓝牙设备扫码字符串异常:无法作为Hive过滤条件问题
蓝牙扫码数据转字符串后Hive过滤失效的排查与解决
问题场景
开发Flutter蓝牙扫码应用时,通过特征值流读取扫码数据并转换为字符串,代码实现如下:
late StreamSubscription<List<int>> _lastValueSubscription; _lastValueSubscription = characteristic.lastValueStream.listen((value) { _value = value; String skuCode = String.fromCharCodes(_value); });
转换得到的skuCode打印显示为正常字符串,但IDE hover时无类型标识,且作为Hive过滤条件时无法返回结果;手动输入相同字符串则能正常匹配。
核心原因
问题根源在于蓝牙设备返回的字节流中包含不可见的控制字符(如换行\n、回车\r、空字符\0等),这些字符打印时无法察觉,但会导致转换后的字符串与手动输入的纯字符串实际不相等。此外,编码不匹配也可能引发类似问题。
解决方案
1. 清理字符串中的隐形控制字符
通过trim()去除首尾空白,再用正则替换掉所有ASCII控制字符:
_lastValueSubscription = characteristic.lastValueStream.listen((value) { _value = value; String rawCode = String.fromCharCodes(_value); // 清理所有不可见控制字符和首尾空白 String skuCode = rawCode.trim().replaceAll(RegExp(r'[\x00-\x1F\x7F]'), ''); });
2. 验证字符串的实际内容
打印字符串长度和每个字符的Unicode码点,对比手动输入的字符串,确认是否存在隐形字符:
print('扫码字符串长度: ${skuCode.length}'); skuCode.runes.forEach((rune) => print('字符码点: $rune')); // 对比手动输入的字符串 String manualSku = '测试扫码码'; print('手动输入字符串长度: ${manualSku.length}'); manualSku.runes.forEach((rune) => print('字符码点: $rune'));
3. 指定正确的编码格式
如果蓝牙设备使用ASCII或UTF-8编码,显式指定解码方式避免默认编码导致的问题:
// 使用UTF-8解码(推荐,兼容更多场景) import 'dart:convert'; String skuCode = utf8.decode(_value).trim(); // 若设备明确使用ASCII编码 String skuCode = ascii.decode(_value).trim();
4. 优化Hive过滤逻辑
确保过滤前先清理字符串,避免隐形字符干扰匹配:
final cleanedSku = skuCode.trim().replaceAll(RegExp(r'[\x00-\x1F\x7F]'), ''); final filteredItems = Hive.box('skuBox').values .where((item) => item.skuCode == cleanedSku) .toList();
内容的提问来源于stack exchange,提问作者Ramiz Girach
相关产品推荐
相关产品推荐

