Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Receive UsbDevice from intent

I'm messing about with the USB host, and following the guidelines on the Android Developers site I've managed to create a Hello World that starts up once a particular USB device is plugged in. However, when I try and "...obtain the UsbDevice that represents the attached device from the intent" it returns null:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent intent = new Intent();
    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);


    // device is always null
    if (device == null){Log.i(TAG,"Null device");}

Here's my manifest:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
        </activity>
    </application>

And my xml/device_filter.xml (I know these are the correct VID and PID because I've got a similar app working using the enumeration method described on the Android Developers site):

<resources>
    <usb-device vendor-id="1234" product-id="1234"/>
</resources>
like image 650
zotty Avatar asked Jul 24 '13 08:07

zotty


2 Answers

When your application is (re-)started due to the USB device attach event, then the device is passed on to the intent when onResume is called. You can get to it using the getParcelableExtra method. For example:

@Override
protected void onResume() {
    super.onResume();

    Intent intent = getIntent();
    if (intent != null) {
        Log.d("onResume", "intent: " + intent.toString());
        if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
            UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (usbDevice != null) {
                Log.d("onResume", "USB device attached: name: " + usbDevice.getDeviceName());
like image 65
fredvanl Avatar answered Nov 18 '22 06:11

fredvanl


I found a workaround (or the intended usage?) thanks to Taylor Alexander. Basically, The way I understand it is that firing the intent that opens the application only opens the application. After that you have to search for and access usb devices as per the Enumerating Devices section of the Android Developers page in the onResume method.

@Override
    public void onResume() {
        super.onResume();

        UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

        while(deviceIterator.hasNext()){
            UsbDevice device = deviceIterator.next();
                // Your code here!
        }

I'm not convinced this is the RIGHT way to do it, but it seems to be working. If anyone has any further suggestions I'd be glad to listen.

like image 1
zotty Avatar answered Nov 18 '22 07:11

zotty