Android Usb Host Receive Data
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;
}
Zapateus
Updated on June 07, 2022Comments
-
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 over 10 yearsthe 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 over 10 yearsI tried your solution with bulktransfer the receivedLenght always return -1 after i get first value.
-
Mike Ortiz over 10 yearsInteresting, 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 over 10 yearsI added a link in my question, you can see same problem with me. Maybe you can find another solution. Thanks for everything
-
Mike Ortiz over 10 yearsCan 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 over 10 yearsIn 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 over 10 yearscan 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 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 over 10 yearsin 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?