2***@qq.com
2***@qq.com
  • 发布:2026-01-22 14:01
  • 更新:2026-01-22 14:02
  • 阅读:46

uni-app APP端蓝牙传输大文件问题

分类:uni-app

我现在用uniapp 开发安卓app,连接蓝牙设备后,可以给设备发送指令,但是在传输大文件的时候,我是做了分割的,一片为20字节,我在微信小程序里面是可以传输成功的,但是在安卓app中,我传输10几片后就报错发送失败了,大家有遇到这个问题吗,我是用的定时器,每10毫米传一次

2026-01-22 14:01 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

该问题请在专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

您遇到的“安卓 APP 端蓝牙写十几片 20 B 后就报错”的现象,在官方文档里已经明确提示过:
“并行调用多次会存在写失败的可能性”
因此,问题并不是出在“20 B 分包”本身,而是 写得太快、没有做写完成等待,以及 MTU 过小

下面给出一条在安卓 APP 端实测可行的大文件传输思路,您可以直接套用:

  1. 连接成功后立刻调大 MTU

    uni.setBLEMTU({  
     deviceId,  
     mtu: 512,          // 安卓 5.1+ 有效,直接给到上限  
     success() {  
       console.log('MTU 已设为 512');  
     }  
    });  
  2. 把 20 B 改成 (MTU-3) 字节(512-3=509 B)分包,大幅减少片数。

  3. 串行写:上一片的 success / complete 回来后再写下一片,不要 10 ms 定时器。
    伪代码示例(递归写法):

    let pos = 0;  
    const chunkSize = 509;          // MTU-3  
    const buffer = /* 您的完整 ArrayBuffer */;  
    
    function writeChunk() {  
     if (pos >= buffer.byteLength) return;   // 传完  
    
     const end = Math.min(pos + chunkSize, buffer.byteLength);  
     const slice = buffer.slice(pos, end);  
    
     uni.writeBLECharacteristicValue({  
       deviceId,  
       serviceId,  
       characteristicId,  
       value: slice,  
       success() {  
         pos = end;  
         writeChunk();              // 成功后再写下一包  
       },  
       fail(e) {  
         console.error('写失败', e);  
         // 这里可做重试或提示  
       }  
     });  
    }  
    writeChunk();  
  4. 如果您的设备一次最多只能收 20 B,那就保持 20 B,但 必须等 success 再写下一包,并且把间隔放宽到 30-50 ms(很多模块空口速率有限,10 ms 太激进)。

  5. 安卓部分机型在 notify 成功后会阻塞写,建议写完一包后再打开 notify,或者把 notify 的 UUID 与写的 UUID 分开。

按以上步骤调整后,安卓 APP 端即可像微信小程序那样稳定地把大文件发完。

内容为 AI 生成,仅供参考

要回复问题请先登录注册