Monday, October 14, 2013

List attached USB devices in USB Host mode

In this exercise, my Android phone (HTC One X) act as USB Host to list attached USB devices via USB OTG cable. It target devices with minSdkVersion="12".

Listed result without any extra device attached.

With card reader attached, via USB OTG cable.

With another Nexus One attached as slave, via USB OTG cable.


To specify the app to be run as UDB Host, add uses-feature of "android.hardware.usb.host", and android:minSdkVersion="12" in AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidusbhost"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-feature android:name="android.hardware.usb.host" />
    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.androidusbhost.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Main Java code.
package com.example.androidusbhost;

import java.util.HashMap;
import java.util.Iterator;

import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
import android.content.Context;

public class MainActivity extends Activity {

 Button btnCheck;
 TextView textInfo;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  btnCheck = (Button) findViewById(R.id.check);
  textInfo = (TextView) findViewById(R.id.info);
  btnCheck.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View arg0) {
    checkInfo();
   }
  });
 }

 private void checkInfo() {
  UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
  Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
  
  String i = "";
  while (deviceIterator.hasNext()) {
   UsbDevice device = deviceIterator.next();
   i += "\n" +
    "DeviceID: " + device.getDeviceId() + "\n" +
    "DeviceName: " + device.getDeviceName() + "\n" +
    "DeviceClass: " + device.getDeviceClass() + " - " 
     + translateDeviceClass(device.getDeviceClass()) + "\n" +
    "DeviceSubClass: " + device.getDeviceSubclass() + "\n" +
    "VendorID: " + device.getVendorId() + "\n" +
    "ProductID: " + device.getProductId() + "\n";
  }
  
  textInfo.setText(i);
 }
 
 private String translateDeviceClass(int deviceClass){
  switch(deviceClass){
  case UsbConstants.USB_CLASS_APP_SPEC: 
   return "Application specific USB class";
  case UsbConstants.USB_CLASS_AUDIO: 
   return "USB class for audio devices";
  case UsbConstants.USB_CLASS_CDC_DATA: 
   return "USB class for CDC devices (communications device class)";
  case UsbConstants.USB_CLASS_COMM: 
   return "USB class for communication devices";
  case UsbConstants.USB_CLASS_CONTENT_SEC: 
   return "USB class for content security devices";
  case UsbConstants.USB_CLASS_CSCID: 
   return "USB class for content smart card devices";
  case UsbConstants.USB_CLASS_HID: 
   return "USB class for human interface devices (for example, mice and keyboards)";
  case UsbConstants.USB_CLASS_HUB: 
   return "USB class for USB hubs";
  case UsbConstants.USB_CLASS_MASS_STORAGE: 
   return "USB class for mass storage devices";
  case UsbConstants.USB_CLASS_MISC: 
   return "USB class for wireless miscellaneous devices";
  case UsbConstants.USB_CLASS_PER_INTERFACE: 
   return "USB class indicating that the class is determined on a per-interface basis";
  case UsbConstants.USB_CLASS_PHYSICA: 
   return "USB class for physical devices";
  case UsbConstants.USB_CLASS_PRINTER: 
   return "USB class for printers";
  case UsbConstants.USB_CLASS_STILL_IMAGE: 
   return "USB class for still image devices (digital cameras)";
  case UsbConstants.USB_CLASS_VENDOR_SPEC: 
   return "Vendor specific USB class";
  case UsbConstants.USB_CLASS_VIDEO: 
   return "USB class for video devices";
  case UsbConstants.USB_CLASS_WIRELESS_CONTROLLER: 
   return "USB class for wireless controller devices";
  default: return "Unknown USB class!";
  
  }
 }
}


layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    <Button
        android:id="@+id/check"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Check USB devices" />
    <TextView
        android:id="@+id/info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


download filesDownload the files.

Next: - List UsbDevice, UsbInterface and UsbEndpoint in USB Host mode



Step-by-step: Android USB Host Mode programming

21 comments:

Unknown said...

manager.getDeviceList() return empty? Why? I can't...=.=

Erik said...

getDeviceList() return empty if no devices are attached, or if USB host mode is inactive or unsupported.

In my case of HTC One X, even no device attached, it return one device.

Have you include minSdkVersion="12" and uses-feature of "android.hardware.usb.host" in AndroidManifest.xml?

What device you test on?

Unknown said...
This comment has been removed by the author.
Unknown said...

I included: minSdkVersion="12" and uses-feature of "android.hardware.usb.host"
in AndroidManifest.xml, but it still return empty.
I test on Sony Xperia P...:(
Please help me!

Erik said...

hello nguyen huy Vo,

I have no Xperia P. I tried to search from Internet. The reason may be:
- Used a in-compatible USB OTG.
- Not enough current provide from Xperia P.
- USB OTG blocked by virus apps, such as McAfee...

Campanha said...

Does it works in a laptop connected to the android?

Erik said...

In my understanding, NO.

When Android connected to PC, via normal USB (NOT OTG), ot act as accessory mode.

Anonymous said...

I think that you should check the file "/system/etc/permissions/handheld_core_hardware.xml" of your phone.

The xml file need the line ""

Anonymous said...

I think that you should check the xml file "/system/etc/permissions/handheld_core_hardware.xml" of your phone.

The xml file need
< feature name="android.hardware.usb.host" />

so that the android device could support usb host development.

Erik said...

hello Anonymous,

I have check my handheld_core_hardware.xml, there are no feature name="android.hardware.usb.host". But it should support USB Host mode.

Anonymous said...

Thank you this code is really helpful, I have some issue, When I connected first time it display all devices correctly. But when I disconnected the usb hub, this is still displaying list of devices because device data still present in manager.getDeviceList().
When I restarted the tab it worked fine again first time. In next time I again got same issue. How to clear list manager.getDeviceList() when usb device disconnected.

Erik said...

Hello Upendra Singh,

Yes, I have the same problem on HTC One X. But not on Samsung S3 and Galaxy Nexus. I think it is the problem of the device.

Anonymous said...

There are so many methods
mUsbManager.getDeviceList().values().clear();
mUsbManager.getDeviceList().values().remove(device);
mUsbManager.getDeviceList().values().removeAll(device)

but I still don't know what is the use of these methods. After doing all above this, mUsbManager.getDeviceList().values() is still showing usb devices.

Anonymous said...

It is possible to send the SMS from the PC to mobile via USB

Anonymous said...

id like to connect printer on Android tablet is this code is working

Erik said...

Sorry, I have no idea about this!

Unknown said...

Nice tutorial... I've already tried this code in eclipse and running with emulator... I connect the USB device, smart card reader-ACR122U, it doesn't work well, when I click the button (Check USB devices), the emulator force to closed... Hmmm, any advice? Thank you

Anonymous said...

Hai andr.oid Eric.Can you tell me how to get the list of attached usb devices with its volume names.I tried your code but it was returning the path of the connected usb devices

Anonymous said...

Thank you very much for such a useful code. but can you please tell me how to read data from usb otg

Mayank Langalia said...

Thank you so much for sharing the code but I wanted to know that I want path [Attached USB Device] and create dynamic folder and storing the content on it. if you have any idea please help me out on the same ....

Anonymous said...

Hi Team,

I am testing above code Panasonic tablet where it has usb port to insert the pendrive . when i run above sample it gives below 6 usb list eventhough there is no pendrive connected.


02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/004/004
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 239 - USB class for wireless miscellaneous devices
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 2

02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/003/003
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 239 - USB class for wireless miscellaneous devices
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 2

02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/001/002
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 224 - USB class for wireless controller devices
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 1

02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/003/004
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 239 - USB class for wireless miscellaneous devices
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 2

02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/003/005
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 0 - USB class indicating that the class is determined on a per-interface basis
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 0

02-08 11:54:39.840: D/Testing(2752): DeviceName: /dev/bus/usb/004/003
02-08 11:54:39.840: D/Testing(2752): DeviceClass: 0 - USB class indicating that the class is determined on a per-interface basis
02-08 11:54:39.840: D/Testing(2752): DeviceSubClass: 0

Is anyone face same issue?