更新记录

1.0.0(2026-10-31)

  • [新增] 安卓串口通信 UTS 插件,基于 Android-Serialport(v2.1.3 源码编译,内置 libs/serialport-2.1.3.aar)
  • [新增] 串口设备枚举(设备名 / 设备节点路径 / 驱动名)
  • [新增] 打开、关闭串口,支持波特率 / 数据位 / 停止位 / 校验位 / 流控 / open flags
  • [新增] 接收监听(文本 / Hex / Base64 三种编码同时返回)
  • [新增] 发送文本 / Hex / Base64 数据
  • [新增] 粘包处理:不处理、固定长度、长度字段变长、首尾特殊字符
  • [新增] 循环发送(可设间隔)
  • [新增] 多串口并行(index 1~5)
  • [新增] 串口属性读写、是否打开查询、资源释放

平台兼容性

uni-app(4.72)

Vue2 Vue2插件版本 Vue3 Vue3插件版本 Chrome Safari app-vue app-vue插件版本 app-nvue app-nvue插件版本 Android Android插件版本 iOS 鸿蒙
√ 1.0.0 √ 1.0.0 × × √ 1.0.0 √ 1.0.0 5.0 1.0.0 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × - × × × × - × ×

uni-app x(4.72)

Chrome Safari Android Android插件版本 iOS 鸿蒙 微信小程序
× × 5.0 1.0.0 × × ×

zy-serial-port(安卓串口通信 UTS 插件)

安卓串口操作 UTS 原生插件,支持设置串口、波特率、停止位、数据位、校验位、流控以及延迟,支持粘包处理解决分包问题,支持多串口操作(最多 5 路串口同时打开,各自独立的参数、粘包方式与收发监听,互不干扰),支持无 root 操作,支持 RS485,插件支持 uniapp 和 uniapp x。

直接打开 Linux 串口设备节点(/dev/ttyS1、/dev/ttyMSM0、/dev/ttyUSB0 等)进行收发, 不依赖 USB Host 权限申请,适合工业平板、POS、门禁、称重、扫码、传感器等自带串口的设备。

功能

能力 说明
设备枚举 SerialPortFinder 读取 /proc/tty/drivers 与 /dev,返回设备名、节点路径、驱动名
打开 / 关闭 SerialPort(JNI),支持任意波特率(含非标准波特率)、停止位、数据位、校验位、流控、open flags
多串口 index 1~5,各自独立维护参数、粘包方式与监听,可同时打开
接收 由独立接收线程持续读取,数据通过 onData 回调(文本 / Hex / Base64 同时返回)
发送 文本(UTF-8)/ Hex / Base64
粘包处理 不处理、固定长度、长度字段变长、首尾特殊字符(对齐库的 4 个 StickPackageHelper)
循环发送 可设间隔,startLoopSend / stopLoopSend
属性读写 端口、波特率、停止位、数据位、校验位、流控、循环发送间隔、是否打开、当前粘包方式

平台支持:仅 Android(minSdk 21,ABI:armeabi-v7a / arm64-v8a)。

注意事项

  1. 必须使用自定义基座:插件内置原生 aar 与 so,标准基座无法调用,请制作自定义基座后运行。
  2. 设备节点权限:打开串口需要当前应用对设备节点有读写权限。
    • 设备节点权限为 666 / 属主为当前应用时可直接打开;
    • 否则库会尝试执行 su + chmod 666 <节点>,仅 root 设备有效;
    • 两者都不满足时 open 回调 9240004(无读写权限)。
  3. 串口参数只能在未打开时修改:与库行为一致,setProperties 在串口已打开时修改 端口/波特率/数据位/停止位/校验位/流控会回调 9240006,请先 close 再设置(delay 随时可改)。
  4. 粘包:默认 none(读到多少返回多少)。协议有定长/长度字段/首尾标识时请先 setStickPackage, 否则一次回调可能是半包或多包拼接。
  5. 接收线程与调用线程:接收、发送、打开、关闭都在内部工作线程执行,回调统一切回主线程, 可以在回调里直接更新页面状态。
  6. 页面 onUnload / 应用退出前建议调用 releaseResources(),关闭全部串口并清空监听。

快速开始

<template>
    <view>
        <button @click="doOpen">打开串口</button>
        <button @click="doSend">发送</button>
        <text>{{ recvHex }}</text>
    </view>
</template>

<script>
    import {
        getDevices,
        open,
        close,
        write,
        onData,
        releaseResources
    } from '@/uni_modules/zy-serial-port'

    export default {
        data() {
            return {
                recvHex: ''
            }
        },
        onLoad() {
            getDevices({
                success: (res) => {
                    console.log('串口设备', res.devices)
                    // [{ name: 'ttyS1 (16650 serial)', path: '/dev/ttyS1', driver: '16650 serial' }]
                },
                fail: (err) => console.error(err.errCode, err.errMsg)
            })
        },
        onUnload() {
            releaseResources({})
        },
        methods: {
            doOpen() {
                open({
                    index: 1,
                    port: '/dev/ttyS1',
                    baudRate: 9600,
                    dataBits: 8,
                    stopBits: 1,
                    parity: 0,
                    flowControl: 0,
                    success: (res) => {
                        console.log('已打开', res)
                        // 打开成功后再注册监听
                        onData({
                            index: 1,
                            format: 'hex',
                            onData: (data) => {
                                // data: { index, port, size, hex, text, base64, time, timestamp }
                                this.recvHex = data.hex
                            },
                            onError: (err) => console.error('接收异常', err.errCode, err.errMsg)
                        })
                    },
                    fail: (err) => console.error('打开失败', err.errCode, err.errMsg)
                })
            },
            doSend() {
                write({
                    index: 1,
                    text: 'hello',
                    success: (res) => console.log('已发送', res.bytes, '字节'),
                    fail: (err) => console.error(err.errCode, err.errMsg)
                })
            }
        }
    }
</script>

API

所有方法均为异步,返回 success / fail / complete;fail 回调为 UniError(含 errCode、errMsg、errSubject)。

设备枚举

方法 说明
getDevices(options) 获取串口设备列表,success({ devices: SerialPortDevice[] })
type SerialPortDevice = {
    name: string   // 'ttyS1 (16650 serial)'
    path: string   // '/dev/ttyS1',open 时作为 port 传入
    driver: string // '16650 serial'
}

打开 / 关闭

方法 说明
open(options) 打开串口并启动接收线程,success(SerialPortProperties)
close(options?) 关闭串口,同时停止接收与循环发送、清空监听

open 参数:

参数 类型 默认 说明
index number 1 串口索引,1~5
port string 必传 设备节点路径,如 /dev/ttyS1
baudRate number 9600 波特率,支持任意值
stopBits number 1 停止位:1 / 2
dataBits number 8 数据位:5 / 6 / 7 / 8
parity number 0 0 无 / 1 奇 / 2 偶 / 3 Space / 4 Mark
flowControl number 0 0 无 / 1 硬件(RTS/CTS) / 2 软件(XON/XOFF)
flags number 0 Android open(2) 标志位(库内部已固定 O_RDWR)
delay number 500 循环发送间隔(毫秒)

属性

方法 说明
isOpen(options?) success({ value: boolean })
getProperties(options?) success(SerialPortProperties)
setProperties(options?) 只修改传入的字段,success(SerialPortProperties)
type SerialPortProperties = {
    index: number
    port: string
    baudRate: number
    stopBits: number
    dataBits: number
    parity: number
    flowControl: number
    delay: number
    isOpen: boolean
    stickPackageType: string // 'none' | 'fixed' | 'variable' | 'specified'
}

发送

write({
    index: 1,
    text?: string,   // UTF-8 文本
    base64?: string, // 二进制(Base64)
    hex?: string,    // '00 01 FF' / '0x00,0x01' / '0001FF'
    success: (res) => {} // res.bytes:写入字节数
})

优先级 hex > base64 > text;hex 支持空格/逗号/短横线/冒号/下划线分隔符与 0x 前缀,奇数位自动左补 0。

接收监听

onData({
    index: 1,
    format?: 'hex' | 'text' | 'base64', // 默认 'hex',仅影响 format 字段
    onData: (res) => {},   // 收到完整一包数据(多次)
    onError: (err) => {},  // 接收线程异常(多次)
    success: () => {},     // 注册成功
    fail: (err) => {}
})

offData({ index: 1 })  // 取消监听(不关闭串口)
type SerialPortData = {
    index: number
    port: string
    size: number
    hex: string      // 大写十六进制,无分隔符
    text: string     // UTF-8 解码文本
    base64: string   // Base64(NO_WRAP)
    time: string     // 'hh:mm:ss.SSS'
    timestamp: number
}

每个串口索引同时只有一个监听,重复注册会覆盖。

粘包处理

setStickPackage({
    index: 1,
    type: 'fixed',   // 'none' | 'fixed' | 'variable' | 'specified'
    length: 16,      // fixed:包长度
    // variable
    byteOrder: 1,    // 1 大端 / 2 小端
    lenSize: 2,      // 长度字段占用字节数
    lenIndex: 0,     // 长度字段起始下标
    offset: 0,       // 整包长度 - 长度字段值
    // specified
    head: '^',       // 包头
    tail: '$',       // 包尾
    isHex: false     // head/tail 是否按十六进制解析
})

协议示例(type+dataLen+data+md5,即 2 + 2 + N + 8):lenIndex = 2、lenSize = 2、offset = 12。

循环发送

startLoopSend({ index: 1, text: 'AT\r\n', delay: 1000 }) // 或 hex: '41 54 0D 0A'
stopLoopSend({ index: 1 })

资源释放

releaseResources() // 关闭全部串口、停止循环发送、清空监听

错误码

错误码 说明
9240001 参数错误
9240002 串口未打开
9240003 串口已打开
9240004 打开串口失败(含无读写权限)
9240005 串口读写失败
9240006 设置串口参数失败(已打开状态下不允许修改)
9240007 关闭串口失败
9240008 获取串口设备列表失败
9240009 串口索引无效(仅 1~5)
9240010 粘包参数错误
9240011 循环发送启动失败
9240012 串口设备不存在或无权限访问
9240013 释放资源失败

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

串口收发的数据仅在本机与外部串口设备之间传输,不会上传至任何服务器

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。