以下是几个开源的 Android 串口通信库:
1. SerialPort:https://github.com/felHR85/SerialPort
这是一个非常流行的 Android 串口通信库,支持多种设备和多种波特率,并且提供了非常详细的文档和示例代码。
2. android-serialport-api:https://github.com/cepr/android-serialport-api
这是一个简单易用的 Android 串口通信库,支持多种设备和多种波特率,并且提供了示例代码和文档。
3. usb-serial-for-android:https://github.com/mik3y/usb-serial-for-android
这是一个支持 USB 转串口通信的 Android 库,可以连接到 FTDI、PL2303 等 USB 转串口芯片,并且提供了非常详细的文档和示例代码。
以上三个库都是开源的,可以在 GitHub 上获取源码和文档。
使用 usb-serial-for-android 库 里面有例子,但发现里面有两个比较大的问题,第一个就是 插入的时候要直接启动 主界面,哪怕在程序里面时候,也需要重新进入。二一个就是,在AndroidManifest.xml 里面设置的广播过滤器 device_fitler.xml 完全不起作用。如果看这个文章同行需要使用我的demo源码可以移步传送门。不过在此之前强烈建议看看Github上的例程。如果理解能力强可以直接搬运Service源码即可。
源码处理了:
1、App运行时USB插拔事件
2、App启动检查USB是否存在
3、USB是否为串口设备(因为USB存储设备插入时也可以触发插拔事件)
4、启停处理
5、收发处理
闲言少叙!!!!
Service 源码:
package com.apandserial.ConnectUtils.Manger;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import com.apandserial.ConnectUtils.driver.UsbSerialDriver;
import com.apandserial.ConnectUtils.driver.UsbSerialPort;
import com.apandserial.ConnectUtils.driver.UsbSerialProber;
import com.apandserial.ConnectUtils.util.SerialInputOutputManager;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/***************************
*Create By Jay_Song
*Date:2023/5/17 Time:9:36
***************************/
public class ConnectService extends Service {
private final static String TAG = "USB 插拔信息";
private final static String USB_SERIALPORT_ATTCHED = "HR_USB_SERIALPORT_ATTCHED";
private final static String USB_SERIALPORT_DETACHED = "HR_USB_SERIALPORT_DETACHED";
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private UsbSerialPort mUsbPort;
private UsbSerialDriver mUsbDriver;
private UsbDeviceConnection musbDeviceConnection;
private SerialInputOutputManager mSerialIoManager;
public final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(USB_SERIALPORT_ATTCHED);
filter.addAction(USB_SERIALPORT_DETACHED);
registerReceiver(Br_UsbActionProc, filter);
IntentFilter permissionintent = new IntentFilter();
permissionintent.addAction(ACTION_USB_PERMISSION);
registerReceiver(Br_UsbPermissionProc, permissionintent);
CheckUsbDevice();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private final BroadcastReceiver Br_UsbPermissionProc = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) {
return;
}
switch (action) {
case ACTION_USB_PERMISSION: {
UsbManager usbManager = (UsbManager) getBaseContext().getSystemService(Context.USB_SERVICE);
PendingIntent mPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, new Intent(ACTION_USB_PERMISSION), 0);
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
if (usbManager.hasPermission(usbDevice)) {
InitSerialPort(usbManager, usbDevice);
}
}
}
}
}
};
/**
* 初始化串口操作
* @param usbManager
* @param usbDevice
*/
private void InitSerialPort(UsbManager usbManager, UsbDevice usbDevice) {
Log.d(TAG, "Checkpermission: VID =" + usbDevice.getVendorId() + " PID =" + usbDevice.getProductId());
mUsbDriver = UsbSerialProber.getDefaultProber().probeDevice(usbDevice);
mUsbPort = mUsbDriver.getPorts().get(0);
musbDeviceConnection = usbManager.openDevice(usbDevice);
try {
mUsbPort.open(musbDeviceConnection);
mUsbPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
mSerialIoManager = new SerialInputOutputManager(mUsbPort, mSerialPortEventListener);
mExecutor.execute(mSerialIoManager);
} catch (IOException e) {
e.printStackTrace();
}
}
private final BroadcastReceiver Br_UsbActionProc = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
switch (intent.getAction()) {
case USB_SERIALPORT_ATTCHED:
Log.d(TAG, "onReceive: USB 插入处理");
CheckUsbDevice();
break;
case USB_SERIALPORT_DETACHED:
Log.d(TAG, "onReceive: USB 拔出处理");
if(mUsbPort!=null)
{
try {
mUsbPort.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (musbDeviceConnection!=null)
{
musbDeviceConnection.close();
}
mSerialIoManager.stop();
break;
}
}
};
private void CheckUsbDevice() {
UsbManager usbManager = (UsbManager) getBaseContext().getSystemService(Context.USB_SERVICE);
PendingIntent mPendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, new Intent(ACTION_USB_PERMISSION), 0);
for (final UsbDevice usbDevice : usbManager.getDeviceList().values()) {
Log.d(TAG, "CheckUsbDevice: VID =" + usbDevice.getVendorId() + " PID =" + usbDevice.getProductId());
mUsbDriver = UsbSerialProber.getDefaultProber().probeDevice(usbDevice);
if (mUsbDriver==null)
{
Log.d(TAG, "CheckUsbDevice:非法设备");
return;
}
if (usbManager.hasPermission(usbDevice)) {
InitSerialPort(usbManager,usbDevice); //具有权限 直接启动
} else {
/**先申请权限**/
usbManager.requestPermission(usbDevice, mPendingIntent);
}
}
}
public static class Br_UsbAction extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
switch (intent.getAction()) {
case UsbManager.ACTION_USB_DEVICE_ATTACHED: {
Log.d(TAG, "onReceive: USB 插入");
Intent bintent = new Intent();
bintent.setAction(ConnectService.USB_SERIALPORT_ATTCHED);
context.sendBroadcast(bintent);
}
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED: {
Log.d(TAG, "onReceive: USB 拔出");
Intent bintent = new Intent();
bintent.setAction(ConnectService.USB_SERIALPORT_DETACHED);
context.sendBroadcast(bintent);
}
break;
}
}
}
private final SerialInputOutputManager.Listener mSerialPortEventListener =
new SerialInputOutputManager.Listener() {
@Override
public void onNewData(byte[] data) {
String str = new String(data);
Log.d(TAG, "onNewData: " + str);
mSerialIoManager.writeAsync(data);
}
@Override
public void onRunError(Exception e) {
}
};
}
在AndoridManifest.xml里面添加
<receiver
android:name=".ConnectUtils.Manger.ConnectService$Br_UsbAction"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</receiver>
<service android:name="com.apandserial.ConnectUtils.Manger.ConnectService" />
通过Actitity 启动ConnectService即可!!!!!
调试结果:
插入后自动识别并开启串口
将收到的信息打印以后发送回去(串口最简单的调试方式):
private final SerialInputOutputManager.Listener mSerialPortEventListener =
new SerialInputOutputManager.Listener() {
@Override
public void onNewData(byte[] data) {
String str = new String(data);
Log.d(TAG, "onNewData: " + str);
mSerialIoManager.writeAsync(data);
}
@Override
public void onRunError(Exception e) {
}
};
PC串口助手调试结果
拔出事件:文章来源:https://www.toymoban.com/news/detail-678064.html
拔出时候需要判断设备状态并关闭串口:文章来源地址https://www.toymoban.com/news/detail-678064.html
case USB_SERIALPORT_DETACHED:
Log.d(TAG, "onReceive: USB 拔出处理");
if(mUsbPort!=null)
{
try {
mUsbPort.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (musbDeviceConnection!=null)
{
musbDeviceConnection.close();
}
mSerialIoManager.stop();
break;
}
到了这里,关于Android Usb(OTG)串口通信,Service 后台服务实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!