如何在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
相关产品推荐
相关产品推荐

