uni-app无法直接连接串口,必须依赖原生插件(如Fvv-UniSerialPort)桥接安卓/iOS底层能力;H5和小程序均不支持,因JS运行在WebView中无系统级硬件访问权限,navigator.serial在移动端浏览器亦不可用。

uni-app 本身不能直接连接串口设备,必须依赖原生插件封装安卓/iOS 底层能力。H5 环境完全不可用,小程序也不支持——这是硬限制,不是配置问题。
为什么 uni.scanCode 或 navigator.serial 不行
uni.scanCode 是给 App 和小程序设计的,H5 下调不起摄像头;navigator.serial 是 Web Serial API,仅 Chromium 109+ 桌面版支持,微信内置浏览器、安卓 WebView、iOS WKWebView 全都不认。你在真机上 console.log(navigator.serial) 会是 undefined。
- uni-app 的 JS 运行在 WebView 里,没有操作系统级硬件访问权限
- 串口(如
/dev/ttyUSB0、/dev/ttyS1)属于系统设备节点,JS 无法绕过原生层直接打开 - 所谓“跨端”,在串口场景下只适用于安卓 + iOS 原生插件桥接,不包括 H5
Fvv-UniSerialPort 插件怎么装和初始化
这是目前社区最活跃、文档最全的串口插件,专为 uni-app 原生扩展设计。关键不是 npm install,而是原生层注册。
- 在 HBuilderX 中,右键项目 → “添加原生插件” → 选择已下载的
Fvv-UniSerialPort插件包(.unipkg 格式),不要用 npm 引入 - 检查
manifest.json的app-plus → plugins是否已自动注入,类似:{"Fvv-UniSerialPort": {"version": "1.2.0", "provider": "xxx"}} - 运行前必须手动在安卓设备上开启“USB 调试”和“安装未知应用”权限,部分设备还需额外授予“串口访问”专项权限(如华为/小米的“USB 设备管理”开关)
- JS 端调用前必须用
uni.requireNativePlugin('Fvv-UniSerialPort')获取实例,不能 import
如何正确获取设备列表并打开串口
别硬写 /dev/ttyS1,真实设备路径千差万别。动态枚举 + 用户确认才是正路。
- 先调
serialPort.getAllDeviceList(),它返回的是原始路径数组,比如["/dev/ttyUSB0", "/dev/ttyS0"],但某些定制 ROM 可能返回空或格式异常 - 对每个路径尝试
serialPort.open({path: item, baudRate: 9600}),用timeout参数防卡死(建议设 1500ms) - 打开成功后立即发一个握手指令(如
AT\r\n或设备协议定义的 ping 帧),靠响应判断是否真连上了目标设备,而非只是占了个串口 - 关闭串口必须显式调
serialPort.close(),否则下次打开可能报EBUSY错误
数据收发与粘包处理怎么写
串口是字节流,不是消息队列。你收到的 onData 回调可能一次来半帧、两次拼一帧、三次混两帧——这非常常见,尤其在高波特率或弱电干扰环境下。
- 绝不能直接
new TextDecoder().decode(buffer)就当字符串用;先转成Uint8Array,再按协议头尾(如 0x7E 开始、0x7F 结束)或定长截取 - 推荐用缓冲区累积:声明
let buffer = new Uint8Array(0),每次onData触发时buffer = concat(buffer, newBuf),然后 while 循环剥出完整帧 - 发送数据前务必用
TextEncoder编码或手动构造Uint8Array,传字符串过去大概率乱码或截断 - 如果设备协议含校验(CRC/Checksum),一定要在 JS 层做校验,失败帧丢弃,别交给业务逻辑处理
最容易被忽略的点是:不同安卓厂商对 USB OTG 的兼容策略差异极大。测试阶段必须覆盖华为(EMUI)、小米(HyperOS)、三星(One UI)及主流工业平板(如优博讯 DT50U),光用模拟器或某一台手机验证等于没测。


















