安卓串口设备未列出,主因是硬件接线错误、usb权限未动态申请或设备路径不在系统白名单;参数错误则多因波特率、校验位等不匹配;数据乱码因误将字节流当字符串处理,需用uint8array解析并按协议拆包。

串口设备在安卓上根本没列出来?先确认硬件和权限
插件调用 serialPort.getAllDeviceList() 或 serialPort.getAllDevicePath() 返回空数组,不是插件坏了,大概率是底层根本没识别到设备。常见原因有三个:
• 硬件接线不对:TTL/RS232电平不匹配、TX/RX反接、没共地;
• 缺少 USB 权限:安卓 6.0+ 必须动态申请 android.permission.USB_PERMISSION,且首次连接时系统会弹窗提示,用户点“拒绝”后插件就永远拿不到设备;
• 设备路径不在白名单:某些定制安卓系统(如优博讯、新大陆PDA)会限制可访问的串口路径,比如只允许 /dev/ttyS3,而插件默认扫描的是通用路径,需要手动在原生层补充配置(如修改 config_serialPorts 数组)。
串口参数设错导致收不到数据?波特率和校验位必须严丝合缝
即使设备列表能刷出来,打开串口后也收不到数据,90% 是参数不一致。IC卡读卡器常用 9600 或 19200 波特率,但有些工业设备用 115200;数据位通常是 8,停止位 1,但部分老设备要求停止位为 2;校验位更易被忽略——多数设备用 None,但也有用 Odd/Even 的。插件的 openSerialPort 方法必须传入完全匹配的参数对象:
serialPort.openSerialPort({
path: '/dev/ttyS3',
baudRate: 19200,
dataBits: 8,
stopBits: 1,
parity: 'none', // 注意大小写,不是 'None' 或 'NONE'
flowControl: false
}, success => { ... }, fail => { ... })
如果不确定参数,最稳的办法是用安卓串口调试工具(如 SerialTool)连上同一设备,抄下它实际使用的配置。
收到的数据是乱码或断断续续?别直接当字符串处理
串口传的是原始字节流,不是 UTF-8 文本。你看到的“乱码”,很可能是十六进制指令(比如 IC 卡返回的 0x02 0x3A 0x46 0x03),或者 ASCII 字符混着控制符。插件回调里拿到的 data 是 ArrayBuffer,必须用 Uint8Array 解析:
serialPort.onDataReceived(data => {
const uint8 = new Uint8Array(data)
console.log('原始字节:', Array.from(uint8)) // 打印十六进制数组,方便比对协议文档
// 不要直接 data.toString() —— 会崩,尤其含 0x00 时
})
另外,串口没有消息边界,一次 onDataReceived 可能只来半个包,也可能攒了三四个包。必须按设备协议定义的帧头(如 0x02)、长度域或帧尾(如 0x03)做粘包/拆包,不能指望“每次回调就是一条完整指令”。
插件集成后真机跑不了?离线包和 manifest.json 配置必须咬死
插件已从 DCloud 插件市场下线,现在只能用离线包。最容易漏的三处是:
• 离线包解压后,文件夹名必须和插件 ID 完全一致(比如 Fvv-UniSerialPort,不能是 fvv-uniserialport 或带版本号);
• manifest.json 的 app-plus.plugins 下,键名必须和插件 ID 一致,且 provider 字段不能留空或填占位符(离线包里 plugin.json 有真实值);
• HBuilderX 打包时必须勾选“使用自定义基座”,否则原生插件不会被打进去——云打包默认用标准基座,不带任何原生插件。
最后提醒一句:串口通信没有重连机制,设备热拔插、休眠唤醒后,closeSerialPort() 和重新 openSerialPort() 是必须手动做的,别指望插件自动兜底。











