Android Usb Host Receive Data

16,813

Which condition fails in your loop? (request.queue(buffer, bufferMaxLength) == true) or (connection.requestWait() == request)? If it's the second, I might suggest using .equals() instead of the reference comparison ==.

Have you tried to use bulk transfer instead of requests?

private UsbManager mManager; 
private UsbDevice  mDevice;
private UsbDeviceConnection mDeviceConnection;
private UsbInterface mInterface;
private UsbEndpoint mEndpointIn;   

public void run() {
    while (mEndpointIn != null && mDeviceConnection != null) {
        byte[] recordIn = new byte[mEndpointIn.getMaxPacketSize()];
        int receivedLength = mDeviceConnection.bulkTransfer(mEndpointIn, recordIn,
                                                       recordIn.length, mTimeout);
        if (receivedLength > -1) passDataToListener(recordIn);
    }
}

public void initializeCommunication(Context context) throws UsbDeviceException {

    mInterface = findHidInterface();

    if (mManager != null && mDevice != null && mInterface != null) {
        mDeviceConnection = mManager.openDevice(mDevice);

        if (mDeviceConnection != null) {
            if (mDeviceConnection.claimInterface(mInterface, true)) {
                UsbEndpoint usbEndpointOut = null;
                UsbEndpoint usbEndpointIn = null;

                //
                // Look for Interrupt endpoints
                //
                for (int i = 0; i < mInterface.getEndpointCount(); i++) {
                    UsbEndpoint usbEndpoint = mInterface.getEndpoint(i);

                    if (usbEndpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
                        if (usbEndpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
                            usbEndpointOut = usbEndpoint;

                        } else {
                            usbEndpointIn = usbEndpoint;
                        }
                    }
                }

                if (usbEndpointOut == null || usbEndpointIn == null) {
                    Log.w(DEBUG, "No USB endpoints found.");
                }

                mEndpointOut = usbEndpointOut;
                mEndpointIn = usbEndpointIn;

            } else {
                mDeviceConnection.close();
                Log.w(DEBUG, "USB claim interface failed.");
            }
        } else {
            Log.w(DEBUG, "USB open device failed.");
        }
    } else {
        Log.w(DEBUG, "Some essential USB variables were null.");
    }
}

/**
 * Find the HID interface.
 * 
 * @return
 *      Return the HID interface if found, otherwise null.
 */
private UsbInterface findHidInterface() {
    if (mDevice != null) {
        final int interfaceCount = mDevice.getInterfaceCount();

        for (int interfaceIndex = 0; interfaceIndex < interfaceCount; interfaceIndex++) {
            UsbInterface usbInterface = mDevice.getInterface(interfaceIndex);

            //
            // Can add UsbInterface.getInterfaceSubclass() and 
            // UsbInterface.getInterfaceProtocol() for more specifics.
            //

            if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
                return usbInterface;
            }
        }

        Log.w(DEBUG, "HID interface not found.");
    }

    return null;
}
Share:
16,813
Zapateus
Author by

Zapateus

Updated on June 07, 2022

Comments

  • Zapateus
    Zapateus almost 2 years

    I try to reading data from my evalboard. It is Stellaris EKK-LM4F232 Evalutaion Kit. It has five buttons. I push a button on board and send data to my android device. For example, i push one times, and board send to 1, and second times send to 2.... I receive the first value (it mean 1) from android device when i push the button first time. But when i push the button again, i can't receive any other values like 2 ,3 ,4 ,... . Here is my code for reading. It read continuously when it is start. Can you help me?

    public void startDataRecieve() {
        new Thread(new Runnable() {
    
            @Override
            public void run() {
    
                UsbEndpoint endpoint = null;
    
                for (int i = 0; i < intf.getEndpointCount(); i++) {
                    if (intf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
                        endpoint = intf.getEndpoint(i);
                        break;
                    }
                }
                UsbRequest request = new UsbRequest(); // create an URB
                boolean initilzed = request.initialize(connection, endpoint);
    
                if (!initilzed) {
                    Log.e("USB CONNECTION FAILED", "Request initialization failed for reading");
                    return;
                }
                while (true) {
                    int bufferMaxLength = endpoint.getMaxPacketSize();
                    ByteBuffer buffer = ByteBuffer.allocate(bufferMaxLength);
    
    
                    if (request.queue(buffer, bufferMaxLength) == true) {
                        if (connection.requestWait() == request) {
                            String result = new String(buffer.array());
                                Log.i("GELEN DATA : ", result);
                                listener.readData(result);
                        }
                    }
                }
    
            }
        }).start();
    }
    

    If you can't understand very well the same question is here asked by one Android bulkTransfer return -1 when read data but there is really some data in the buffer

    After the discusstion with @Mike Ortiz I put all my code in here. When I click the buttonSend android device send "START" command to device then reading start. When i send to android device to first value i can get it but after first value i don't get any value from usb device. I am sure the usb device sends the values.

    public class MainActivity extends Activity implements Runnable {
    
    private static final String TAG = "MAIN ACTIVITY TEST ";
    
    private Button buttonConnect;
    private Button butonSend;
    private Button buttonDisconnect;
    private TextView textViewResult;
    private UsbDevice device;
    
    private Thread readThread;
    private UsbManager usbManager;
    private UsbDeviceConnection connection;
    private UsbInterface usbInterface;
    private UsbEndpoint usbEndpointIn;
    private UsbEndpoint usbEndpointOut;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        initView();
    
        PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(usbReceiver, filter);
    
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
    
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
    
            if (device.getVendorId() == 7358 && device.getProductId() == 3) {
                this.device = device;
                usbManager.requestPermission(device, mPermissionIntent);
                break;
            }
        }
    
        butonSend.setOnClickListener(new OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
                usbInterface = device.getInterface(0);
                connection = usbManager.openDevice(device);
                connection.claimInterface(usbInterface, false);
    
                for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
                    UsbEndpoint end = usbInterface.getEndpoint(i);
                    if (end.getDirection() == UsbConstants.USB_DIR_IN) {
                        usbEndpointIn = end;
    
                    } else {
                        usbEndpointOut = end;
                    }
                }
    
                //SEND START COMMAND TO  THE USB DEVICE; 
                int result = connection.bulkTransfer(usbEndpointOut, "START".getBytes(), "START".getBytes().length, 1000);
                Log.e("SEND RESULT", result + "");
    
    
                //START READING in run method
                readThread = new Thread(MainActivity.this);
                readThread.start();
    
    
    
    
            }
        });
    
        buttonDisconnect.setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                mRunning = false;
                //readThread.stop();
                connection.releaseInterface(usbInterface);
                connection.close();
                Log.e(TAG, "Connection CLosed.");
    
            }
        });
    }
    
    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) {
                            Toast.makeText(MainActivity.this, "Cihaza izin verildi", Toast.LENGTH_LONG).show();
                        }
                    } else {
                        Toast.makeText(MainActivity.this, "Cihaza izin verilmedi.", Toast.LENGTH_LONG).show();
                        Log.d(TAG, "permission denied for device " + device);
                    }
                }
            }
        }
    };
    
    private boolean mRunning;
    
    private void initView() {
        butonSend = (Button) findViewById(R.id.buttonSend);
        buttonConnect = (Button) findViewById(R.id.buttonConnect);
        textViewResult = (TextView) findViewById(R.id.textViewResult);
        buttonDisconnect = (Button) findViewById(R.id.buttonDisconnect);
    }
    
    @Override
    public void run() {
        mRunning = true; 
    
        //READ VALUE UNTIL DISCONNECT
        while (mRunning) {
    
            byte[] bytes = new byte[usbEndpointIn.getMaxPacketSize()];
            int result = connection.bulkTransfer(usbEndpointIn, bytes, bytes.length, 1000);
            if(result > 0)
            Log.e("RESULT : " + result, "  VALUE : " + new String(bytes));
    
    
        }
        Log.d("Thread", "STOPPPED");
    
    } 
    

    }

  • Zapateus
    Zapateus over 10 years
    the problem is (connection.requestWait() == request). But I can get first value. For example i send 1 first time from usb device. I can get it but second time i send 2 , i don't take the value in android device. If this condition is not correct, why does it work in when i get first value?
  • Zapateus
    Zapateus over 10 years
    I tried your solution with bulktransfer the receivedLenght always return -1 after i get first value.
  • Mike Ortiz
    Mike Ortiz over 10 years
    Interesting, I use similar code to what I've posted in a project of my own and it works for multiple messages. My next suggestion would be to use a USB Analyzer to confirm the kit is actually sending data to the phone after the first button press.
  • Zapateus
    Zapateus over 10 years
    I added a link in my question, you can see same problem with me. Maybe you can find another solution. Thanks for everything
  • Mike Ortiz
    Mike Ortiz over 10 years
    Can you post the rest of your relevant code? Do you call mDeviceCommunication.claimInterface(intf, true); , etc? Are you communicating over the correct type of interface? I believe you want to be looking for a HID interface, specifically, and only endpoints from that specific interface. You can download the app "USB Device Info" to enumerate the endpoints and interfaces for your usb device.
  • Zapateus
    Zapateus over 10 years
    In usb device has one usbInterface and two endpoints. They are bulkEndpoint and one of them in, the other is out. I updated my question and add all my code.
  • Zapateus
    Zapateus over 10 years
    can you tell me , what is your usb device and what is your android device? And I want to learn your devices endpoint types? Please
  • Mike Ortiz
    Mike Ortiz over 10 years
    @Zapateus The interface is HID and the end point type is bulk. I added some code around initializing communication, which I use in my own project. I think my code might be more robust around grabbing the correct interface and at the very least, has a good amount of error logging to let you know know where things are going wrong. Hope it works for you.
  • Zapateus
    Zapateus over 10 years
    in your solution there is if (usbEndpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) clause but my endpoint types are USB_ENDPOINT_XFER_BULK. Do you know what is difference. And my interface type is not HID vendor specific type. But i think ,the problem is my endpoint types? isn't is?