Android Usb(OTG)串口通信,Service 后台服务实现方式

以下是几个开源的 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串口助手调试结果

 拔出事件:

拔出时候需要判断设备状态并关闭串口:

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

猜你喜欢

转载自blog.csdn.net/MSONG93/article/details/130730467
今日推荐