Can't receive broadcast Intent of UsbManager.ACTION_USB_DEVICE_ATTACHED/UsbManager.ACTION_USB_DEVICE_DETACHED

user2645035 picture user2645035 · Aug 2, 2013 · Viewed 7.9k times · Source

I am coding an USB host App recently, but it's stucked because I can't detect the device attached/detached event, I followed the coding note of http://developer.android.com/guide/topics/connectivity/usb/host.html and refer to other's coding in the network, After checking several times, I still can't find the problem. After my debugging, it seems that the UsbManager.ACTION_USB_DEVICE_ATTACHED/UsbManager.ACTION_USB_DEVICE_DETACHED intent is not happened, Because I try to use Context.sendBroadcast() to send a customized Intent, and my BroadcastReceiver can receive the intent. But when I attach/detach the USB device, the BroadcastReceiver don't run. The cellphone I use is HTC One-X, I am sure the OTG function is correct as the mouse function working perfectly. Here is my code piece.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.launcher);
    mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
    if(mUsbManager == null) {
        Log.d(TAG, "mUsbManager is null");
    }

    // listen for new devices
    IntentFilter filter = new IntentFilter();
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
  // filter.addAction("MyTest");
    registerReceiver(mUsbReceiver, filter);

}

The BroadcastReceiver

BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "mUsbReceiver.onReceive start");
        String action = intent.getAction();
        UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            setDevice(device);
        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            if (mDevice != null && mDevice.equals(device)) {
                setDevice(null);
            }
        }
    }
};

Manifest.xml

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

<application>
    <activity android:name=".USBActivity"
        android:label="USBActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    <!--     <receiver android:name=".mUsbReceiver"> -->

        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
        </intent-filter>

        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />
        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
            android:resource="@xml/device_filter" />
   <!--     </receiver> -->

        </activity>
</application>

device_filter in res/xml, all 3 settings are tried and no-use:

 <?xml version="1.0" encoding="utf-8"?>
 <resources>
  <!-- iCooby mouse -->
  <!--     <usb-device vendor-id="15d9" , /> -->
  <!--     <usb-device vendor-id="5593" product-id="2637"/> -->
    <usb-device />
 </resources>

If someone know what's happened? or tell me how to detect if the broadcast intent is active or not, thanks very much.

Answer

fredvanl picture fredvanl · Oct 15, 2013

Perhaps a bit late, but it may help others. Just solved a similar problem with detecting the insertion of USB devices. It turns out that - because you specified an intent filter in the manifest - Android calls onResume when something is plugged in. You might try adding this:

@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)) {
            // Do your thing ...
        }

Then you also do not need the registerReceiver() call in onCreate(). Please also keep in mind that the ID's in the intent filter are in decimal. So you would have to convert the values as presented by command line tools like 'lsusb'.