Android设备检测到USB设备插入,用户授予连接权限后,即可进行设备的连接流程。
/**
* 连接设备
*/
private void connectDevice(UsbDevice usbDevice){
//Android标准的api,判断设备是否有连接权限
if (mUsbManager.hasPermission(usbDevice)){
//Android标准的API,打开设备,返回的是UsbDeviceConnection对象,也是Android标准API
connection = mUsbManager.openDevice(usbDevice);
try {
open(connection);
setParameters(ScaleDevice.BAUDRATE, ScaleDevice.DATABITS,
UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
} catch (IOException e) {
e.printStackTrace();
try {
mScaleDevicePort.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
}
@Override
public void open(UsbDeviceConnection connection) throws IOException {
if (mConnection != null) {
throw new IOException("Already opened.");
}
mConnection = connection;
try {
//接下来获取用于通信的interface
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
//获取每一个interface,并
UsbInterface usbIface = mDevice.getInterface(i);
//声明当前interface,也就是占用当前的interface,true表示force,是否强制占用。返回boolean值,表示是否占用成功。
if (mConnection.claimInterface(usbIface, true)) {
Log.d(TAG, "claimInterface " + i + " SUCCESS");
} else {
Log.d(TAG, "claimInterface " + i + " FAIL");
}
}
//获取最后一个UsbInterface,这可能是当前类型的UsbDevice的特性,用最后一个UsbInterface进行通信。
UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
//获取最后一个UsbInterface的通信端点的数量,并进行遍历
for (int i = 0; i < dataIface.getEndpointCount(); i++) {
//遍历UsbInterface包含所有的UsbEndpoint
UsbEndpoint ep = dataIface.getEndpoint(i);
//判断UsbEndpoint的类型,也即是type。这种类型的UsbDevice使用USB_ENDPOINT_XFER_BULK这种类型的UsbEndpoint进行通信。
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_IN) {//再判断UsbEndpoint的数据方向,很明显IN表示读入数据。
mReadEndpoint = ep;//获取了读端点
} else {
mWriteEndpoint = ep;//获取了写端点,这种类型是UsbConstants.USB_DIR_OUT
}
}
}
//接下来是进行一些请求参数的配置,应该是根据不同的UsbDevice会进行不同的请求参数配置。
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_ENABLE);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, MCR_ALL | CONTROL_WRITE_DTR | CONTROL_WRITE_RTS);
setConfigSingle(SILABSER_SET_BAUDDIV_REQUEST_CODE, BAUD_RATE_GEN_FREQ / DEFAULT_BAUD_RATE);
} finally {
if (!opened) {
try {
close();
} catch (IOException e) {
// Ignore IOExceptions during close()
}
}
}
}
@Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity)throws IOException {
//这里就是进行相应的波特率/停止位/数据位等配置参数的设置
setBaudRate(baudRate);
//数据位
int configDataBits = 0;
switch (dataBits) {
case DATABITS_5:
configDataBits |= 0x0500;
break;
case DATABITS_6:
configDataBits |= 0x0600;
break;
case DATABITS_7:
configDataBits |= 0x0700;
break;
case DATABITS_8:
configDataBits |= 0x0800;
break;
default:
configDataBits |= 0x0800;
break;
}
switch (parity) {
case PARITY_ODD:
configDataBits |= 0x0010;
break;
case PARITY_EVEN:
configDataBits |= 0x0020;
break;
}
switch (stopBits) {
case STOPBITS_1:
configDataBits |= 0;
break;
case STOPBITS_2:
configDataBits |= 2;
break;
}
setConfigSingle(SILABSER_SET_LINE_CTL_REQUEST_CODE, configDataBits);
}
//设置波特率
private void setBaudRate(int baudRate) throws IOException {
byte[] data = new byte[] {
(byte) ( baudRate & 0xff),
(byte) ((baudRate >> 8 ) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff)
};
int ret = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SILABSER_SET_BAUDRATE,
0, 0, data, 4, USB_WRITE_TIMEOUT_MILLIS);
if (ret < 0) {
throw new IOException("Error setting baud rate.");
}
}
通过以上过程就完成了连接过程。
针对上述过程,每一种不同的UsbDevice有不同的表现形式。但是大体过程和调用的Android API都是相同的。不同的UsbDevice可以通过vendorId和ProductId进行判断。
以上过程,流程图如下: