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

66 篇文章 0 订阅

安卓开发中的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 findAllDrivers(final UsbManager usbManager);
1
2
3
4
5
6
7
8
9
10
  -方法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);
1
2
3
4
5
6
7
8
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);
}

1
2
3
4
5
6
7
8
9
10
11
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;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-构建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);
            }
        });
    }
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*在源码中看到了一个很特别的Activity间传参的方式,我将它记录在我的另一篇博客中.

原文:https://blog.csdn.net/STchaoL/article/details/72716624

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值