• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Cannot read serial data using USB Host


Jan 4, 2023
Hi all,

I am trying to read serial data from a USB device using my Samsung phone as the host. I have followed the USB Host Overview tutorial closely but I cannot get any data from the device. I am performing async read using UsbRequest as the device is continually streaming data I would like to read.

My code:
class TransferThread extends Thread {
    private static final String TAG = "MainActivity";
    private static int TIMEOUT = 5000;
    private static int BUFFER_LENGTH = 32768;
    private byte[] buffer = new byte[BUFFER_LENGTH];

    UsbDeviceConnection connection;
    UsbEndpoint endpoint;

    TransferThread(UsbDeviceConnection connection, UsbEndpoint endpoint) {
        this.connection = connection;
        this.endpoint = endpoint;

    public void run() {
        Log.v(TAG, "New thread started");

        UsbRequest usbRequest = new UsbRequest();
        if(usbRequest.initialize(connection, endpoint)) {
            Log.v(TAG, "USB request successfully initialised");
        final ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_LENGTH);
        if(usbRequest.queue(byteBuffer)) {
            Log.v(TAG, "USB request successfully queued");
        if(connection.requestWait() == usbRequest) {
            Log.v(TAG, "Successfully returned USB request result");
            Log.v(TAG, "Has array: " + byteBuffer.hasArray());
            Log.v(TAG, "Data: " + Arrays.toString(byteBuffer.array()));
            Log.v(TAG, "Data: " + byteBuffer.toString());
        else {
            Log.v(TAG, "Failed to return USB request");

        Log.v(TAG, "byteBuffer.ToString(): " + byteBuffer.toString());

/*        int numBytesTransferred = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT);
        if(numBytesTransferred >= 0) {
            Log.v(TAG, "Bulk transfer successful");
        else {
            Log.v(TAG, "Bulk transfer failed");

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if(device != null){
                            Log.v(TAG,"Permission granted for device");
                    else {
                        Log.d(TAG, "permission denied for device " + device);

    protected void onCreate(Bundle savedInstanceState) {

        Log.v(TAG, "Running Main activity onCreate");

        // Enumerate USB devices
        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
        Log.v(TAG, String.format("%d device(s) found by UsbManager", deviceList.size()));
        for (HashMap.Entry<String, UsbDevice> entry : deviceList.entrySet()) {
            String key = entry.getKey();
            Log.v(TAG, "Device name: " + key);
        UsbDevice device = deviceList.get("/dev/bus/usb/002/002");
        Log.v(TAG, "Device info: " + device.toString());
        Log.v(TAG, String.format("Device has %d configuration(s)", device.getConfigurationCount()));
        Log.v(TAG, String.format("Device has %d interface(s)", device.getInterfaceCount()));

        // Obtain permission to communicate with a device
        PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_MUTABLE);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(usbReceiver, filter);
        manager.requestPermission(device, permissionIntent);

        int interfaceNumber = 0;
        int endpointNumber = 0;
        UsbInterface usbInterface = device.getInterface(interfaceNumber);
        Log.v(TAG, String.format("Got interface %d", interfaceNumber));
        Log.v(TAG, "Interface name: " + usbInterface.getName());
        Log.v(TAG, "Interface class: Vendor specific " + usbInterface.getInterfaceClass());
        UsbEndpoint endpoint = usbInterface.getEndpoint(endpointNumber);
        Log.v(TAG, String.format("Got endpoint %d", endpointNumber));
        int endpointType = endpoint.getType();
        if(endpointType == UsbConstants.USB_ENDPOINT_XFER_CONTROL) {
            Log.v(TAG, "Endpoint type: endpoint zero");
        if(endpointType == UsbConstants.USB_ENDPOINT_XFER_ISOC) {
            Log.v(TAG, "Endpoint type: isochronous endpoint");
        if(endpointType == UsbConstants.USB_ENDPOINT_XFER_BULK) {
            Log.v(TAG, "Endpoint type: bulk endpoint");
        if(endpointType == UsbConstants.USB_ENDPOINT_XFER_INT) {
            Log.v(TAG, "Endpoint type: interrupt endpoint");
        int endpointDir = endpoint.getDirection();
        if(endpointDir == UsbConstants.USB_DIR_IN) {
            Log.v(TAG, "Endpoint direction: IN (device to host)");
        if(endpointDir == UsbConstants.USB_DIR_OUT) {
            Log.v(TAG, "Endpoint direction: OUT (host to device)");

        UsbDeviceConnection connection = manager.openDevice(device);
        connection.claimInterface(usbInterface, true);

        TransferThread thread = new TransferThread(connection, endpoint);

Using endpoint 0 (interrupt type) I get the following data when I run the code:

I'm not sure if I'm using requestWait incorrectly or if I'm using the wrong endpoint or some other setting. Anyb help would be appreciated, thanks!
hi casjkent2
you could try is to make sure that you have the necessary permissions to access the device. You can do this by adding the following code before you start the transfer thread:

UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
manager.requestPermission(device, mPermissionIntent);

You will also need to register a broadcast receiver to handle the permission request response. You can do this by adding the following code to the onCreate method of your activity:

IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver, filter);

Make sure that you have added the necessary permissions to your app's manifest file:

<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-permission android:name="android.permission.USB_HOST" />
Upvote 0


We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.