Detection when disconnecting USB device on Android

I have an Android app that needs to determine when the USB peripherals are plugged in or unplugged. It works fine when the peripheral device is first connected, but I do not receive any notification (i.e. I do not receive an Intent whose action is ACTION_USB_DEVICE_DETACHED ) when it is subsequently disconnected.

Here is the relevant part of my AndroidManifest.xml :

 <activity android:name=".LauncherActivity"> <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" /> </activity> 

It may also be useful to note that LauncherActivity exists only to start the Service when the device is connected and to stop the service when it is disconnected. In any case, LauncherActivity always finish es directly. All this happens in LauncherActivity.onCreate .

Any ideas?

+6
source share
5 answers

USB_DEVICE_DETACHED is a broadcast intent, so you might want to declare BroadcastReceiver in the manifest with the appropriate intent filter for the detached action, as well as with attached metadata. The same goes for USB_ACCESSORY_DETACHED, for whom it is interesting.

Summary:
USB_XXX_ATTACHED is the intention of activity
USB_XXX_DETACHED is the intent of the broadcast

(where XXX = DEVICE | ACCESSORIES)

See: http://developer.android.com/guide/components/intents-filters.html

“There is no coincidence in these messaging systems: intent broadcasts are delivered only to broadcast receivers, not to actions or services.”

+10
source

Try using USB_STATE as shown below.

It will be launched both attached and remote to the same receiver, and in the receiver you can determine whether it was attached or disconnected.

 IntentFilter filter = new IntentFilter(); filter.addAction("android.hardware.usb.action.USB_STATE"); 

Recipient:

 public class USBReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { if (intent.getExtras().getBoolean("connected")) { //do your stuff } } } 
+6
source

So, I did not receive ACTION_USB_DEVICE_DETACHED Intent to go to LauncherActivity ; I don’t know what the deal is, perhaps something that I misunderstand about intent filters or Activity callbacks.

The solution I used comes from a post related to Pratik. Basically, I took all USB_DEVICE_DETACHED from AndroidManifest.xml . Then, in the onCreate method of Service I registered a BroadcastReceiver as follows:

 @Override public void onCreate() { detachReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) stopSelf(); } }; IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(detachReceiver, filter); } 

A bit inconvenient, and I'm still wondering why just adding USB_DEVICE_DETACHED to the <intent-filter> from LauncherActivity didn't work, but it does what I need.

+3
source

For what it's worth, I had the same problem because the action was paused and then resumed when the device was disconnected.
Since the receiver is not registered in the OnPause() method just before receiving ACTION_USB_DEVICE_DETACHED , your application never receives a notification.

0
source

The fix that worked for me was to unregister onPause() and register again on onResume() :

 @Override public void onPause() { super.onPause(); stopIOManager(); if(m_UsbReceiver!=null) unregisterReceiver(m_UsbReceiver); } @Override public void onResume() { super.onResume(); startIOManager(); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); registerReceiver(m_UsbReceiver, filter); } 

However, although the application seems to always receive the DETACH event, it does not receive the ATTACHED event from time to time. Then I need to plug in and unplug the USB connector, and it usually works after one or two attempts. I am sure that I am to blame for this strange behavior in the OS.

0
source

All Articles