Android 串口-usb-serial-for-android
app.build
//usb-serialimplementation 'com.github.mik3y:usb-serial-for-android:3.9.0'
工具类
public class SerialPortManager implements SerialInputOutputManager.Listener {private static final String TAG = "SerialPortManager";// 单例模式private static volatile SerialPortManager instance;private Context context;private UsbSerialPort serialPort;private SerialInputOutputManager ioManager;private SerialPortListener listener;// 串口参数private int baudRate = 115200;private int dataBits = UsbSerialPort.DATABITS_8;private int stopBits = UsbSerialPort.STOPBITS_1;private int parity = UsbSerialPort.PARITY_NONE;private boolean sendReadFlag; //发送:true ,接收:falseprivate SerialPortManager(Context context) {this.context = context.getApplicationContext();}public static SerialPortManager getInstance(Context context) {if (instance == null) {synchronized (SerialPortManager.class) {if (instance == null) {instance = new SerialPortManager(context);}}}return instance;}public boolean isSendReadFlag() {return this.sendReadFlag;}public void setSendReadFlags(boolean sendReadFlag) {this.sendReadFlag = sendReadFlag;}/*** 打开串口** @param device USB设备* @return 是否打开成功*/public boolean openPort(UsbDevice device) {UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);if (driver == null) {if (listener != null) {listener.onError(new IOException("No compatible USB serial driver found"));}return false;}if (driver.getPorts().isEmpty()) {if (listener != null) {listener.onError(new IOException("No serial port available on this device"));}return false;}// 大多数设备只有一个端口,所以获取第一个端口serialPort = driver.getPorts().get(0);UsbDeviceConnection connection = usbManager.openDevice(driver.getDevice());if (connection == null) {if (listener != null) {listener.onError(new IOException("Failed to open USB device connection"));}return false;}try {serialPort.open(connection);serialPort.setParameters(baudRate, dataBits, stopBits, parity);// 可选:设置流控制serialPort.setRTS(true);serialPort.setDTR(true);startIoManager();return true;} catch (Exception e) {closePort();if (listener != null) {listener.onError(e);}return false;}}/*** 关闭串口*/public void closePort() {stopIoManager();if (serialPort != null) {try {serialPort.close();} catch (IOException e) {// 忽略关闭错误}serialPort = null;}}/*** 设置串口参数*/public void setSerialPortParams(int baudRate, int dataBits, int stopBits, int parity) {this.baudRate = baudRate;this.dataBits = dataBits;this.stopBits = stopBits;this.parity = parity;if (isPortOpen() && serialPort != null) {try {serialPort.setParameters(baudRate, dataBits, stopBits, parity);} catch (IOException e) {if (listener != null) {listener.onError(e);}}}}/*** 发送数据** @param data 要发送的数据* @return 是否发送成功*/public boolean sendData(byte[] data) {if (!isPortOpen() || serialPort == null) {if (listener != null) {listener.onError(new IOException("Serial port is not open"));}return false;}try {serialPort.write(data, 2000);//超时时间(毫秒)return true;} catch (IOException e) {if (listener != null) {listener.onError(e);}return false;}}/*** 启动IO管理器*/private void startIoManager() {if (serialPort != null) {ioManager = new SerialInputOutputManager(serialPort, this);ioManager.setWriteBufferSize(5*1024);ioManager.setReadBufferSize(5*1024);ioManager.start();}}/*** 停止IO管理器*/private void stopIoManager() {if (ioManager != null) {ioManager.stop();ioManager = null;}}/*** 串口是否打开*/public boolean isPortOpen() {return serialPort != null;}public boolean checkedConnection(Context context) {if (!isPortOpen()) {DialogHelper.showTip(context, context.getString(R.string.please_connect_device));return false;}return true;}// ==================== SerialInputOutputManager.Listener ====================@Overridepublic void onNewData(byte[] data) {if (listener != null) {listener.onDataReceived(data);}}@Overridepublic void onRunError(Exception e) {closePort();if (listener != null) {listener.onError(e);}}// ==================== Getter & Setter ====================public void setSerialPortListener(SerialPortListener listener) {this.listener = listener;}public interface SerialPortListener {void onDataReceived(byte[] data);void onError(Exception e);}
}
使用:
1)注册
@SuppressLint("UnspecifiedRegisterReceiverFlag")@Overridepublic void onResume() {super.onResume();if (SpUtil.getBoolean(Constant.IS_USE_SERIAL)) {IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);registerReceiver(usbPermissionReceiver, filter);initUsb();}}@Overrideprotected void onDestroy() {super.onDestroy();if (SpUtil.getBoolean(Constant.IS_USE_SERIAL)) {onSerialPortClose();}}
private final BroadcastReceiver usbPermissionReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION_USB_PERMISSION.equals(action)) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {if (device != null) {boolean b = serialPortManager.openPort(device);setConnectImg(b);}} else {LogUtil.d("Permission denied for device " + device);}}}};
2)
private SerialPortManager serialPortManager;private void initUsb() {if (SerialPortManager.getInstance(context).isPortOpen() && CheckConnectUtil.checkedConnection(context))return;// 初始化串口管理器serialPortManager = SerialPortManager.getInstance(this);serialPortManager.setSerialPortListener(this);UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
// LogUtil.d("availableDrivers:"+GsonUtil.getJsonStr(availableDrivers));if (availableDrivers.isEmpty()) {return;}// Open a connection to the first available driver.UsbSerialDriver driver = availableDrivers.get(0);checkUsbPermission(driver.getDevice());}
private static final String ACTION_USB_PERMISSION = "com.android.usb.USB_PERMISSION";private void checkUsbPermission(UsbDevice device) {LogUtil.d("device:" + device.getDeviceName());UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);if (usbManager.hasPermission(device)) {LogUtil.d("已经有权限,可以打开设备");// 已经有权限,可以打开设备boolean b = serialPortManager.openPort(device);setConnectImg(b);} else {LogUtil.d("请求权限");// 请求权限PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0,new Intent(ACTION_USB_PERMISSION), 0);usbManager.requestPermission(device, permissionIntent);}}
3) Activity implements SerialPortManager.SerialPortListener
private final Handler mainLooper = new Handler(Looper.getMainLooper());
@Overridepublic void onDataReceived(byte[] data) {mainLooper.post(() -> {receive(data);});}@Overridepublic void onError(Exception e) {mainLooper.post(() -> {setConnectImg(false);});}
4)
private void receive(byte[] data) {
// LogUtil.d("receiveData:" + HexDump.toHexString(data));TimerCountStart();if (totalData == null) {totalData = new byte[data.length];System.arraycopy(data, 0, totalData, 0, data.length);} else {byte[] data2 = new byte[totalData.length + data.length];System.arraycopy(totalData, 0, data2, 0, totalData.length);System.arraycopy(data, 0, data2, totalData.length, data.length);totalData = data2;}int firstIndex = 0;if (totalData.length > 1) {for (int i = 0; i < totalData.length; i++) {if (totalData[i] == 0 && totalData[i + 1] == 0) {firstIndex = i;break;}}}int num = 0;if (totalData.length > 4) {num = Byte.toUnsignedInt(totalData[firstIndex]) << 24 | Byte.toUnsignedInt(totalData[firstIndex + 1]) << 16 |Byte.toUnsignedInt(totalData[firstIndex + 2]) << 8 | Byte.toUnsignedInt(totalData[firstIndex + 3]) << 0;if (num == (totalData.length - 4)) {TimerCancel();byte[] newData = new byte[totalData.length];System.arraycopy(totalData, 0, newData, 0, totalData.length);totalData = null;byte[] endUse = new byte[num];System.arraycopy(newData, firstIndex + 4, endUse, 0, num);//逻辑处理ReadResponse(new String(endUse));}if ((totalData != null && totalData.length > (num + 4))) {TimerCancel();totalData = null;}}}