哎未雨绸缪 2026-01-28 12:00 采纳率: 0%
浏览 7

uniapp 蓝牙传输文件

uniapp 安卓App 蓝牙分包上传,特征值什么的都拿到了,然后分包上传,前面200片都成功,在200之后时候报错 {"errMsg":"writeBLECharacteristicValue:fail property not support","errCode":10007,"code":10007},这个问题怎么解决,我在微信小程序里面上传是没有任何报错的,可以正常上传,但是在安卓app就会发送失败,有遇到过这个问题的吗?

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-28 12:01
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    你遇到的问题是 在 UniApp 开发的安卓 App 中使用蓝牙分包上传时,第 200 片之后出现 writeBLECharacteristicValue:fail property not support 错误,而在微信小程序中却能正常工作。这表明问题可能与 平台差异、蓝牙协议限制或特性值配置不正确 有关。


    ✅ 问题分析

    1. 错误代码解释

    • errCode: 10007:表示 “property not support”,即 写入的特征值不支持写操作
    • 这个错误通常出现在以下几种情况:
      • 你尝试写入一个只读特征值;
      • 你尝试写入一个未被正确配置为可写(Write)的特征值;
      • 在某些平台上(如 Android),蓝牙连接或特征值状态未正确初始化。

    🧠 原因分析

    1. Android 和微信小程序的蓝牙实现不同

    • 微信小程序使用的是 WeChat 定制的蓝牙 API,底层实现可能对部分特征值有更宽松的处理;
    • UniApp 的原生 Android 实现(基于 uni-app 的 uni-app-plus 或 uni-app 蓝牙模块)可能对蓝牙协议的支持更加严格。

    2. 分包上传的限制

    • 每次写入蓝牙数据时,最大传输长度有限制(通常是 20 bytes 或者 200 bytes,具体取决于设备);
    • 超过这个长度后,需要分包发送,但如果你没有正确设置特征值的写入模式(如是否允许批量写入)或者没有等待上一次写入完成就继续发送,就会导致失败。

    3. 特征值权限问题

    • 有些设备的特征值只能写入一次,或者写入后会进入不可写状态;
    • 如果你在写入第 200 片之后,特征值不再支持写入,就会报错。

    ✅ 解决方案(详细步骤)

    1. 确保特征值支持写入

    • 在连接蓝牙设备前,先通过 getBLEDeviceServicesgetBLEDeviceCharacteristics 获取设备的特征值信息;
    • 确保你正在使用的特征值具有 Write 属性
    uni.getBLEDeviceCharacteristics({
      deviceId: deviceId,
      serviceId: serviceId,
      success: function (res) {
        console.log('characteristics:', res.characteristics);
        // 遍历特征值,确认是否有 write 权限
        for (let char of res.characteristics) {
          if (char.properties.write) {
            console.log('找到可写特征值:', char);
          }
        }
      },
      fail: function (err) {
        console.error('获取特征值失败', err);
      }
    });
    

    2. 控制写入节奏,避免超时或并发写入

    • 每次写入后等待回调再进行下一次写入,防止多个写入请求同时发出,造成冲突。
    function writeData(index) {
      if (index >= totalPackets) return;
    
      const packet = data.slice(index * 20, (index + 1) * 20); // 假设每包 20 字节
      uni.writeBLECharacteristicValue({
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: characteristicId,
        value: packet,
        success: function () {
          console.log(`第 ${index + 1} 包写入成功`);
          setTimeout(() => {
            writeData(index + 1);
          }, 50); // 增加延时,防止并发写入
        },
        fail: function (err) {
          console.error(`第 ${index + 1} 包写入失败`, err);
          // 可以在这里添加重试逻辑
        }
      });
    }
    

    3. 检查是否需要启用写入属性

    • 某些设备的特征值需要先启用写入功能,例如调用 setBLECharacteristicValue 或其他命令来激活写入权限。

    4. 调试建议

    • 使用 蓝牙调试工具(如 nRF Connect)测试你的设备,看是否可以正常写入;
    • 在 Android 设备上,查看 系统日志(logcat),看看是否有更详细的错误信息;
    • 尝试将写入包大小从 200 改为更小的值(如 100),观察是否仍然报错。

    🛠️ 代码修改示例(关键部分)

    原始代码片段(可能存在并发写入问题)

    for (let i = 0; i < totalPackets; i++) {
      uni.writeBLECharacteristicValue({ ... });
    }
    

    修改后的代码(顺序写入 + 延时)

    function sendPackets() {
      let index = 0;
      function nextPacket() {
        if (index >= totalPackets) return;
    
        const packet = data.slice(index * 20, (index + 1) * 20);
        uni.writeBLECharacteristicValue({
          deviceId: deviceId,
          serviceId: serviceId,
          characteristicId: characteristicId,
          value: packet,
          success: () => {
            console.log(`第 ${index + 1} 包写入成功`);
            index++;
            setTimeout(nextPacket, 50); // 增加延时,避免并发
          },
          fail: (err) => {
            console.error(`写入失败:`, err);
            // 失败处理逻辑
          }
        });
      }
    
      nextPacket();
    }
    

    ✅ 总结

    | 问题点 | 解决方法 | |--------|-----------| | 写入特征值不支持 | 确认特征值具有 write 权限 | | 分包写入冲突 | 控制写入节奏,顺序发送 | | 平台差异 | 微信小程序和 Android 蓝牙实现不同 | | 写入超时 | 添加延时,等待上一包写入完成 |


    如果你能提供具体的设备型号、服务 ID、特征值 ID,我可以进一步帮你分析。也可以考虑使用第三方蓝牙库(如 ble.jsnoble)来替代 UniApp 自带的蓝牙模块,以获得更好的兼容性。

    评论

报告相同问题?

问题事件

  • 创建了问题 1月28日