You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android应用中读取串口?STM设备CAN通信前置技术咨询

Android平板与STM设备串口通信实现指南

一、推荐的SDK/API选择

作为Android开发新手,优先选择封装成熟的第三方库降低开发门槛:

  • android-serialport-api:针对Android内置串口(如RS232/485)的经典库,封装了JNI层操作逻辑,无需从零实现底层串口读写。
  • usb-serial-for-android:若使用USB转串口连接STM设备,该库支持CH340、PL2303等主流芯片,简化了USB Host模式下的设备枚举与通信流程。

如果需要原生实现,可直接通过File类操作串口设备节点(需处理JNI权限),或使用Android原生UsbManager API(针对USB转串口场景),但新手更推荐上述第三方库。

二、核心实现步骤

1. 配置权限

在AndroidManifest.xml中添加必要权限:

<!-- 内置串口访问相关 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- USB转串口相关 -->
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />

Android 6.0及以上版本,需动态申请文件读写或USB权限。

2. 初始化串口连接

内置串口示例(基于android-serialport-api)

// 替换为你的串口设备节点(如/dev/ttyS0)和波特率
SerialPort serialPort = new SerialPort(new File("/dev/ttyS0"), 9600, 0);
InputStream inputStream = serialPort.getInputStream();
OutputStream outputStream = serialPort.getOutputStream();

// 启动子线程读取串口数据
new Thread(() -> {
    byte[] buffer = new byte[1024];
    int readLen;
    try {
        while ((readLen = inputStream.read(buffer)) != -1) {
            // 解析STM发送的CAN消息(需和硬件端约定协议格式)
            String rawData = new String(buffer, 0, readLen);
            
            // 切换到UI线程更新界面
            runOnUiThread(() -> {
                // 示例:将数据显示到TextView
                // tvData.setText(rawData);
            });
        }
    } catch (IOException e) {
        e.printStackTrace();
        // 处理连接异常(如串口断开)
    }
}).start();

USB转串口示例(基于usb-serial-for-android)

UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceMap = usbManager.getDeviceList();

// 遍历设备,通过VID/PID识别目标USB转串口设备
for (UsbDevice device : deviceMap.values()) {
    if (device.getVendorId() == YOUR_DEVICE_VID && device.getProductId() == YOUR_DEVICE_PID) {
        // 请求USB访问权限
        PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.your.app.USB_PERMISSION"), 0);
        usbManager.requestPermission(device, permissionIntent);
        
        // 权限通过后打开串口
        UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);
        if (driver != null && !driver.getPorts().isEmpty()) {
            UsbSerialPort port = driver.getPorts().get(0);
            try {
                port.open(usbManager.openDevice(device));
                // 配置串口参数(波特率、数据位、停止位、校验位)
                port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
                
                // 启动读取线程
                new Thread(() -> {
                    byte[] buffer = new byte[1024];
                    int readLen;
                    try {
                        while ((readLen = port.read(buffer, 1000)) > 0) {
                            // 处理CAN消息数据
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        break;
    }
}

三、关键注意事项

  • 串口设备节点确认:不同平板的内置串口节点可能不同,可通过adb shell执行ls /dev/tty*命令查看可用节点。
  • 权限问题:部分平板的内置串口节点仅允许root或系统应用访问,需与硬件厂商沟通开放普通应用权限;USB转串口需确保设备VID/PID正确,并申请到USB权限。
  • 数据协议解析:必须与STM端约定CAN消息的封装格式(如帧头、数据长度、校验位),避免解析错误。
  • 线程安全:串口读写必须在子线程执行,更新UI时需通过runOnUiThread或Handler切换到主线程,防止ANR。

内容的提问来源于stack exchange,提问作者Nathan Care

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 03:37:44