安卓开发中的USB转串口通讯

来源:互联网 发布:java oracle 读表 编辑:程序博客网 时间:2024/06/05 10:34

安卓开发中的USB转串口通讯

本文使用GitHub上开源的”hoho.android.usbserial”USB串口库。该库基于“Android USB Host API”,驱动完全由java开发,无需root,不限内核,很是方便。

简介Anddroid USB Host API

原文链接

android.hardware.usb包下提供了USB开发的相关类。
我们需要了解UsbManager、UsbDevice、UsbInterface、UsbEndpoint、UsbDeviceConnection、UsbRequest、UsbConstants。
1、UsbManager:获得Usb的状态,与连接的Usb设备通信。
2、UsbDevice:Usb设备的抽象,它包含一个或多个UsbInterface,而每个UsbInterface包含多个UsbEndpoint。Host与其通信,先打开UsbDeviceConnection,使用UsbRequest在一个端点(endpoint)发送和接收数据。
3、UsbInterface:定义了设备的功能集,一个UsbDevice包含多个UsbInterface,每个Interface都是独立的。
4、UsbEndpoint:endpoint是interface的通信通道。
5、UsbDeviceConnection:host与device建立的连接,并在endpoint传输数据。
6、UsbRequest:usb 请求包。可以在UsbDeviceConnection上异步传输数据。注意是只在异步通信时才会用到它。
7、UsbConstants:usb常量的定义,对应linux/usb/ch9.h

安卓串口库(hoho.android.usbserial)

该库包含了CH34X系列等多款USB串口芯片的驱动,且提供UsbSerialDriver接口供用户自定义驱动.
常用的类及接口:

1.UsbSerialDriver接口

该接口的实现类作为USB串口的驱动,需要重写其中的getDevice方法getPorts方法,其中getDevice()返回一个”原始设备”实例(详见Android USB Host API),getPorts()返回所有可用的UsbSerialPort实例.

2.UsbSerialProber类

  从类名可以看出,该类用于探测可用的USBSerial设备,可以使用它来获取当前可用的USBSerial设备列表.
  -方法getDefaultProber用于获取默认的Prober实例
  -方法findAllDrivers用于获取所有的UsbSerialDriver列表

  /**     * Finds and builds all possible {@link UsbSerialDriver UsbSerialDrivers}     * from the currently-attached {@link UsbDevice} hierarchy. This method does     * not require permission from the Android USB system, since it does not     * open any of the devices.     *     * @param usbManager     * @return a list, possibly empty, of all compatible drivers     */    public List<UsbSerialDriver> findAllDrivers(final UsbManager usbManager);

  -方法probeDevice用于根据兼容UsbDevice获取单个UsbSerialDevice实例

  /**     * Probes a single device for a compatible driver.     *      * @param usbDevice the usb device to probe     * @return a new {@link UsbSerialDriver} compatible with this device, or     *         {@code null} if none available.     */    public UsbSerialDriver probeDevice(final UsbDevice usbDevice);

3.UsbSerialPort接口

  该接口提供了所有的与USB串口设备通讯的方法,通过UsbSerialDriver.getPorts()可以获取该UsbSerialDriver实例的所有端口实例.

4.SerialInputOutputManager类

  这是一个实现了Runnable接口的类,从类名可以看出,该类提供了对串口设备I/O的管理.通过一个UsbSerialPort实例作为参数来构造一个管理器实例,使用时应该为该管理器绑定一个SerialInputOutputManager.Listener实例,该Listener使用回调的方式提供串口数据和串口异常数据
  UsbSerialInputOutputManager.Listener提供了两个抽象方法:onNewData(byte[] data)OnRunError(Exception e).当有收到新数据时将会调用onNewData方法,数据data作为参数传回;运行错误发生时调用onRunError方法,返回异常类实例e.
writeAsync()方法用来”线程安全”的向输出流写数据.

1.获取支持的USB Devices列表。

  首先初始化一个UsbManager的实例,然后用该UsbManger实例做参数,调用UsbSerialProber实例的findAllDrivers方法获取所有的UsbSerialDrivers实例.因为最终需要UsbSrialPort进行通讯,所以在获取所有的UsbSerialDrivers实例后应该调用它的getPorts方法获取其端口
  贴上代码:

    UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);    final List<UsbSerialDriver> drivers =                        UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);    final List<UsbSerialPort> result = new ArrayList<UsbSerialPort>();    for (final UsbSerialDriver driver : drivers) {        final List<UsbSerialPort> ports = driver.getPorts();        Log.d(TAG, String.format("+ %s: %s port%s",            driver, Integer.valueOf(ports.size()), ports.size() == 1 ? "" : "s"));        result.addAll(ports);    }

2.与串口设备通讯

  首先初始化USBSerialPort并且为其设置必要的参数,使用该UsbSerialPort实例来构建一个SerialInputOutputManager对象(manager),并以此对象构建线程并执行.调用manager的writeAsync()方法来写数据,重写onNewData方法来处理读入的数据.
  
-为sPort设置必要的参数并开启端口:

    UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);    UsbDeviceConnection connection = usbManager.openDevice(sPort.getDriver().getDevice());    //初始化一个connection以实现USB通讯,详见Android USB Host API    try {        //开启端口        sPort.open(connection);        //为sPort设置参数        sPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);        } catch (IOException e) {        Log.e(TAG, "Error setting up device: " + e.getMessage(), e);        try {            sPort.close();        } catch (IOException e2) {            // Ignore.        }        sPort = null;        return;    }

-构建SerialInputOutputManager对象并创建执行线程

    //Git的源码中使用了ExecutorService来异步执行线程    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();    //构建Manager对象并为其设置监听器    private SerialInputOutputManager mSerialIoManager = new SerialInputOutputManager(sPort, mListener);    private final SerialInputOutputManager.Listener mListener =            new SerialInputOutputManager.Listener() {        @Override        public void onRunError(Exception e) {            Log.d(TAG, "Runner stopped.");        }        @Override        public void onNewData(final byte[] data) {            SerialConsoleActivity.this.runOnUiThread(new Runnable() {                @Override                public void run() {                    SerialConsoleActivity.this.updateReceivedData(data);                }            });        }    };

*在源码中看到了一个很特别的Activity间传参的方式,我将它记录在我的另一篇博客中.

原创粉丝点击