You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Flutter Blue的ScanResult转换为Android的scanRecord字节数组?

转换思路:将Flutter Blue的Map格式广告数据转为Android风格的scanRecord字节数组

刚好处理过类似的适配场景,给你分享个可行的解决方案。BLE广播包(也就是Android里的scanRecord)本质是由多个广告段拼接而成的,每个广告段的固定格式是:

[长度(1字节), 类型(1字节), 数据(N字节)]
其中「长度」= 1(类型字节的长度) + N(数据字节的长度)

Flutter Blue返回的Map其实是把每个广告段的「类型」和「数据」拆成了键值对,我们只需要把这些键值对重新还原成标准广告段格式,再拼接起来就能得到和Android一致的scanRecord字节数组了。

具体实现步骤(Dart代码)

  1. 初始化一个空的字节列表,用来存放最终的转换结果
  2. 遍历Flutter Blue返回的Map的每一个键值对:
    • 把广告类型(Map的key)转成单个字节(注意:BLE标准广告类型是0-255的uint8范围,有些版本的Flutter Blue会用256表示制造商特定数据,这时候需要映射为标准的0xFF)
    • 计算当前广告段的长度:1(类型字节) + 数据长度,转成单个字节
    • 把「长度字节」「类型字节」「数据字节数组」依次加入总列表
  3. 最终的总列表就是可以直接传入现有解析协议的scanRecord字节数组

代码示例

假设你从Flutter Blue拿到的广告数据是这样的:

Map<int, List<int>> flutterAdvertData = {256: [0,0,0,16,1,57,33,18,0,0,154,10,0]};

转换代码如下:

List<int> convertToAndroidScanRecord(Map<int, List<int>> flutterAdvertData) {
  List<int> scanRecord = [];
  
  for (var entry in flutterAdvertData.entries) {
    int adType = entry.key;
    List<int> adData = entry.value;
    
    // 适配Flutter Blue的特殊类型映射:比如256对应标准制造商数据类型0xFF
    if (adType == 256) {
      adType = 0xFF;
    }
    
    // 计算广告段长度,不能超过BLE的最大限制255
    int segmentLength = 1 + adData.length;
    if (segmentLength > 0xFF) {
      throw Exception("广告段长度超出BLE规范限制(最大255字节)");
    }
    
    // 拼接成标准广告段,加入总列表
    scanRecord.add(segmentLength);
    scanRecord.add(adType);
    scanRecord.addAll(adData);
  }
  
  return scanRecord;
}

注意事项

  • 不同版本的Flutter Blue对广告类型的key定义可能有差异,比如有些版本会用字符串key(比如manufacturerData),你需要根据实际返回的Map结构调整类型映射逻辑
  • 如果你的解析协议依赖设备名称、服务UUID等其他广播字段,要确保Flutter Blue返回的Map中包含这些条目,转换时一起处理进去
  • 测试时可以对比Android端抓包的scanRecord字节数组和转换后的结果,确保格式完全一致

内容的提问来源于stack exchange,提问作者Priadarshan Mega

火山引擎 最新活动