Comunicación del puerto serie USB (OTG) de Android, método de implementación del servicio en segundo plano

Las siguientes son varias bibliotecas de comunicación en serie de Android de código abierto:
1. SerialPort: https://github.com/felHR85/SerialPort
Esta es una biblioteca de comunicación en serie de Android muy popular que admite una variedad de dispositivos y velocidades en baudios, y proporciona documentación muy detallada. y código de muestra.
2. android-serialport-api: https://github.com/cepr/android-serialport-api
Esta es una biblioteca de comunicación de puerto serie de Android fácil de usar que admite múltiples dispositivos y múltiples velocidades en baudios, y proporciona ejemplos de código y documentación.
3. usb-serial-for-android: https://github.com/mik3y/usb-serial-for-android
Esta es una biblioteca de Android que admite comunicación USB a serie y se puede conectar a FTDI, PL2303 y otros chips USB a serie y proporciona documentación muy detallada y código de muestra.
Las tres bibliotecas anteriores son todas de código abierto y el código fuente y la documentación se pueden obtener en GitHub.

Hay ejemplos de uso de la biblioteca usb-serial-para-android , pero descubrí que hay dos problemas relativamente grandes: el primero es iniciar directamente la interfaz principal al insertar, incluso si está en el programa, necesita volver a entrar . La segunda es que el filtro de transmisión device_fitler.xml configurado en AndroidManifest.xml no funciona en absoluto. Si lees este artículo y necesitas usar mi código fuente de demostración, puedes ir al portal . Pero antes de eso, se recomienda encarecidamente echar un vistazo a las rutinas en Github. Si tiene una gran capacidad de comprensión, puede mover directamente el código fuente del Servicio.

Código fuente procesado:

1. Evento de conexión y desconexión del USB cuando la aplicación se está ejecutando

2. La aplicación comienza a verificar si el USB existe.

3. Si el USB es un dispositivo de puerto serie (porque el evento de conexión también se puede activar cuando se inserta el dispositivo de almacenamiento USB)

4. Iniciar y detener el procesamiento

5. Procesamiento de envío y recepción

¡Chismes menos! ! ! !

Código fuente del servicio:

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) {

                }
            };
}

Agregar 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" />

¡Inicie ConnectService a través de Actividad! ! ! ! !

Resultados de la depuración:

 Identifica y abre automáticamente el puerto serie después de la inserción.

Imprima la información recibida y envíela de vuelta (la forma más sencilla de depurar el puerto serie):

 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) {

                }
            };

Resultados de depuración del asistente de puerto serie de PC

 Evento de desconexión:

Al desconectarlo, debe juzgar el estado del dispositivo y cerrar el puerto serie:

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

Supongo que te gusta

Origin blog.csdn.net/MSONG93/article/details/130730467
Recomendado
Clasificación