简介:本文详细解析Android设备串口通信的实现方法,涵盖权限配置、硬件连接、驱动适配及代码实现,提供可落地的开发方案与调试技巧。
串口通信(Serial Communication)通过数据线按位传输数据,采用异步通信协议(如RS-232、RS-485)。Android设备通过USB转串口芯片(如CH340、FT232)或内置串口控制器实现物理层连接,数据传输速率通常为9600-115200bps。
android.permission.USB_PERMISSION及WRITE_EXTERNAL_STORAGE在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.USB_PERMISSION" /><uses-feature android:name="android.hardware.usb.host" />
通过UsbManager检测已连接设备:
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();for (UsbDevice device : deviceList.values()) {if (isSerialDevice(device)) { // 自定义设备识别逻辑PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);usbManager.requestPermission(device, permissionIntent);}}
UsbDeviceConnection connection = usbManager.openDevice(device);UsbInterface usbInterface = device.getInterface(0);UsbEndpoint endpointIn = usbInterface.getEndpoint(0);UsbEndpoint endpointOut = usbInterface.getEndpoint(1);// 配置串口参数(波特率、数据位等需通过控制传输实现)byte[] request = new byte[]{(byte) 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00};connection.controlTransfer(0x40, 0x03, 0x0000, 0x0000, request, 7, 5000);
示例代码:
implementation 'com.github.mik3y3.4.3'
UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);UsbSerialPort port = driver.getPorts().get(0);port.open(connection);port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
private final Handler mHandler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {byte[] buffer = (byte[]) msg.obj;// 处理接收到的数据}};private void startReading(UsbSerialPort port) {new Thread(() -> {byte[] buffer = new byte[1024];while (isRunning) {int size = port.read(buffer, 1000);if (size > 0) {Message msg = mHandler.obtainMessage();msg.obj = Arrays.copyOf(buffer, size);mHandler.sendMessage(msg);}}}).start();}
public boolean sendData(byte[] data) {try {int offset = 0;while (offset < data.length) {int bytesWritten = port.write(data, offset, data.length - offset);if (bytesWritten <= 0) {return false;}offset += bytesWritten;}return true;} catch (IOException e) {e.printStackTrace();return false;}}
SecurityException: User 10153 does not have android.permission.USB_PERMISSIONPendingIntent正确配置
// 自定义Prober示例public class Ch340Prober extends UsbSerialProber {@Overrideprotected UsbSerialDriver getDriver(UsbDevice device) {if (device.getVendorId() == 0x1A86 && device.getProductId() == 0x7523) {return new Ch340Driver(device);}return null;}}
\n或特定字符作为帧结束符
private final BlockingQueue<byte[]> sendQueue = new LinkedBlockingQueue<>(16);private final BlockingQueue<byte[]> receiveQueue = new LinkedBlockingQueue<>(32);
public static int getOptimalBaudRate(UsbDevice device) {if (device.getVendorId() == 0x0403 && device.getProductId() == 0x6001) {return 921600; // FTDI芯片支持高速率}return 115200; // 默认安全速率}
@Overrideprotected void onPause() {super.onPause();if (port != null && port.isOpen()) {port.close();}}
app/├── src/│ ├── main/│ │ ├── java/com/example/serial/│ │ │ ├── SerialManager.java # 串口核心逻辑│ │ │ ├── DeviceDetector.java # 设备检测│ │ │ └── ProtocolParser.java # 数据解析│ │ └── res/│ │ └── xml/device_filter.xml # USB设备过滤配置│ └── AndroidManifest.xml└── build.gradle
device_filter.xml示例:
<resources><usb-device vendor-id="1027" product-id="24597" /> <!-- FTDI示例 --><usb-device class="255" subclass="0" protocol="0" /> <!-- 自定义类设备 --></resources>
public class MultiSerialManager {private final SparseArray<UsbSerialPort> ports = new SparseArray<>();public void addPort(int portId, UsbSerialPort port) {ports.put(portId, port);}public boolean broadcast(byte[] data) {boolean success = true;for (int i = 0; i < ports.size(); i++) {if (!sendData(ports.valueAt(i), data)) {success = false;}}return success;}}
实现Modbus RTU协议示例:
public class ModbusRtu {public static byte[] readHoldingRegisters(int slaveId, int startAddr, int quantity) {byte[] frame = new byte[8];frame[0] = (byte) slaveId;frame[1] = 0x03; // 功能码frame[2] = (byte) (startAddr >> 8);frame[3] = (byte) startAddr;frame[4] = (byte) (quantity >> 8);frame[5] = (byte) quantity;// 计算CRCint crc = calculateCRC(frame, 6);frame[6] = (byte) (crc & 0xFF);frame[7] = (byte) (crc >> 8);return frame;}}
本教程系统覆盖了Android串口开发的全流程,从基础权限配置到高级协议实现均提供了可落地的解决方案。实际开发中建议结合具体硬件特性进行适配,并通过日志系统(如Timber)完善调试信息。对于商业项目,建议采用模块化设计,将串口通信层与业务逻辑解耦,提高代码可维护性。