Android USB Host Communication Android USB Host Communication android android

Android USB Host Communication


I hate to answer my own question but... I got it figured out. I was just mixing up my reads and writes. Additionally the device didn't like the '\n' I was using at the end of my commands. It appears to get along with '\r' much better.

I ended up using android's bulkTransfer for reads and writes. My writes looked like this.

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

And my overridden write method for my BufferedWriter:

@Override

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

The reads were similar:

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

And:

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

This was all just kicked off in a thread like so:

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

Obviously this is just the comm stuff and I'll need to now do something with it (put it in a Service that can report back to a top level UI Activity using a handler). But this part of it is figured out.

A huge thank you to the folks who are working on rosjava (http://code.google.com/p/rosjava/)... They have put together a lot of great projects and their code was very helpful.

Adding my device class to help clarify things.

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

Adding BKReader code:

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