Android的USB主机通信

我正在开发一个利用Android 3.2中的USB Hostfunction的项目。 一般来说,我对USB /串行通信缺乏足够的知识和天分。 我也无法find任何我需要做的很好的示例代码。

我需要从USB通信设备读取。
例如:当我通过Putty连接(在我的PC上)时,input:

>GO 

该设备开始为我喷出数据。 俯仰/滚动/温度/校验。

例如:

 $R1.217P-0.986T26.3*60 $R1.217P-0.986T26.3*60 $R1.217P-0.987T26.3*61 $R1.217P-0.986T26.3*60 $R1.217P-0.985T26.3*63 

我可以从Android设备发送最初的“GO”命令,此时我收到“GO”的回声。

然后没有其他任何后续的读取。

我怎么能:1)发送'去'命令。 2)读取结果数据stream。

我正在使用的USB设备具有以下接口(端点)。

设备类别:通信设备(0x2)

接口:

接口#0类别:通信设备(0x2)端点#0方向:入站(0x80)types:中断(0x3)轮询间隔:255最大数据包大小:32属性:000000011

接口#1类:通信设备类(CDC)(0xa)端点#0地址:129号码:1方向:入站(0x80)types:批量(0x2)轮询间隔(0)最大包大小:32属性:000000010

端点#1地址:2号码:2方向:出站(0x0)types:批量(0x2)轮询间隔(0)最大数据包大小:32属性:000000010

我能够处理权限,连接到设备,find正确的接口并分配端点。 我只是无法弄清楚使用哪种技术来发送初始命令读取随后的数据。 我试过bulkTransfer和controlTransfer的不同组合,没有运气。

谢谢。

我正在使用接口#1,如下所示:

 public AcmDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { Preconditions.checkState(usbDeviceConnection.claimInterface(usbInterface, true)); this.usbDeviceConnection = usbDeviceConnection; UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); Log.d(TAG, "EP " + i + ": " + ep.getType()); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("Not all endpoints found."); } AcmReader acmReader = new AcmReader(usbDeviceConnection, epIn); AcmWriter acmWriter = new AcmWriter(usbDeviceConnection, epOut); reader = new BufferedReader(acmReader); writer = new BufferedWriter(acmWriter); } 

Solutions Collecting From Web of "Android的USB主机通信"

我讨厌回答我自己的问题,但是我知道了。 我只是混淆了我的读写。 此外,该设备不喜欢我在我的命令结束时使用的\ n。 它似乎与'\ r'相得益彰。

我结束了使用android的bulkTransfer读取和写入。 我的写作看起来像这样。

  try { device.getWriter().write(command + "\r"); device.getWriter().flush(); } catch (IOException e) { throw new RuntimeException(e); } 

而我的BufferedWriter的覆写方法:

@覆盖

  public void write(char[] buf, int offset, int count) throws IOException { byte[] buffer = new String(buf, offset, count).getBytes(Charset.forName("US-ASCII")); int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); } 

读数是相似的:

  char[] buffer = new char[BUF_SIZE]; try { BufferedReader reader = device.getReader(); int readBytes = reader.read(buffer); Log.d(TAG, "BYTES READ: " + readBytes); } catch (IOException e) { throw new RuntimeException(e); } String strBuf = new String(buffer).trim(); if (DEBUG) { Log.d(TAG, "Read: " + strBuf); } 

和:

 @Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; } 

这一切都只是在一个像这样的线程开始:

 new Thread() { @Override public void run() { String command = "go"; write(command); while (true) { String coords = read(); } } }.start(); 

显然,这只是通信的东西,我现在需要做一些事情(把它放在一个服务,可以报告回顶级UI活动使用处理程序)。 但是这部分已经解决了。

非常感谢在rosjava( http://code.google.com/p/rosjava/ )上工作的人们,他们汇集了许多优秀的项目,他们的代码非常有帮助。

添加我的设备类,以帮助澄清事情。

 import com.google.common.base.Preconditions; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; import android.util.Log; import java.io.BufferedReader; import java.io.BufferedWriter; /* This class represents a USB device that supports the adb protocol. */ public class BKDevice { // private static final int TIMEOUT = 3000; private final UsbDeviceConnection usbDeviceConnection; private final BufferedReader reader; private final BufferedWriter writer; public static final String TAG = "AcmDevice"; public BKDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { Preconditions.checkState(usbDeviceConnection.claimInterface( usbInterface, true)); this.usbDeviceConnection = usbDeviceConnection; UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); Log.d(TAG, "EP " + i + ": " + ep.getType()); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("Not all endpoints found."); } BKReader acmReader = new BKReader(usbDeviceConnection, epIn); BKWriter acmWriter = new BKWriter(usbDeviceConnection, epOut); reader = new BufferedReader(acmReader); writer = new BufferedWriter(acmWriter); } public BufferedReader getReader() { return reader; } public BufferedWriter getWriter() { return writer; } } 

添加BKReader代码:

 import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.util.Log; import java.io.IOException; import java.io.Reader; import java.nio.charset.Charset; public class BKReader extends Reader { private static final int TIMEOUT = 1000; private final UsbDeviceConnection connection; private final UsbEndpoint endpoint; public BKReader(UsbDeviceConnection connection, UsbEndpoint endpoint) { this.connection = connection; this.endpoint = endpoint; } @Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; } @Override public void close() throws IOException { } }