当前位置: 首页 > ds >正文

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;}}}

http://www.xdnf.cn/news/8309.html

相关文章:

  • Spring Boot——自动配置
  • 如何给文件夹添加编号?批量给文件夹添加数字、字母、日期编号
  • 前端判空:与后端 “千层套路” 的斗智斗勇
  • highCharts生成3D饼图
  • 若依Ruoyi富文本编辑器Quill粘贴图片改成文件上传(不使用base64)
  • 【C/C++】深入解析Linux下C/C++内存管理全攻略(纲要)
  • 从0到1玩转TypeScript:开启类型世界的奇妙冒险
  • 基于 AMDXCVU13P FPGA 的 4 路 100G 光纤 PCIe 低时延高性能计算加速卡
  • MCP Server StreamableHTTP 开发学习文档
  • RT-Thread源码阅读(2)——任务启动与调度
  • ArkTs中的尾随闭包
  • 如何重新设置网络ip地址?全面解析多种方法
  • 第八天 搭建车辆状态监控平台(Docker+Kubernetes) OTA升级服务开发(差分升级、回滚机制)
  • eNSP防火墙实现GRE over IPSec
  • 文件操作和IO-3 文件内容的读写
  • 【Java高阶面经:数据库篇】16、分库分表主键:如何设计一个高性能唯一ID
  • transformer网络
  • 云曦25年春季期中考核复现
  • 【会议推荐|权威出版】2025年电力工程与电气技术国际会议(PEET 2025)
  • Python 训练 day31
  • ssh登录设备总提示密码错误解决方法
  • 使用 Navicat 17 for PostgreSQL 时,请问哪个版本支持 PostgreSQL 的 20150623 版本?还是每个版本都支持?
  • Skia如何在窗口上绘图
  • 突破免疫研究瓶颈!Elabscience IL - 4 抗体 [11B11](APC 偶联)靶向识别小鼠细胞因子
  • 纯JS前端转图片成tiff格式
  • 选择第三方软件检测机构做软件测试的三大原因
  • 从零开始学习QT——第二步
  • Rabbit MQ
  • CSS:vertical-align用法以及布局小案例(较难)
  • Spring AI Alibaba 调用文生语音模型(CosyVoice)