USB device access pop-up suppression? USB device access pop-up suppression? android android

USB device access pop-up suppression?


When you request permission inside your app it seems that the checkbox "use by default for this USB device" does nothing (I am not sure why this checkbox even shows up on this popup.

Instead you should register an intent handler for your activity in the manifest:

<activity     ...    ...    >    <intent-filter>        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />    </intent-filter>    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />  </activity>

You also have to create a filter file in your xml resources, eg res/xml/usb_device_filter:

<?xml version="1.0" encoding="utf-8"?><resources>    <usb-device vendor-id="26214" product-id="26214" /></resources>

The vendor-id and product-id here have to be given in decimal - above both the VID and PID are 0x6666.

What I have given above also works for a USB accessory (that is, where the accessory is the USB host and the android is the device) - in that case the intent-filter should register

<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />

and you also have to include the meta data filter in exactly the same way.

See http://developer.android.com/guide/topics/connectivity/usb/accessory.html and search for the section "Using an intent filter".

EDIT

To conclude - if you register the intent-filter against your activity, the USB permission window will be displayed immediately when the USB device/accessory is connected. If the user checks the "use by default for this USB device" box and then grants permission, this will be remembered and the permission dialog will not be displayed again (unless the app is uninstalled or the user clears the default action from the application manager).

I have put a tiny, terrible, working example project up here:

http://www.locusia.com/examples/permissionTest.zip

You will need to edit res/xml/usb_device_filter.xml, but otherwise this should allow you to test it out very quickly.

For services...

It seems that a service cannot receive the USB intents. I got around this by making a hidden activity which would then re-broadcast the intents.

I define it in my manifest like this:

<activity    android:name=".activities.UsbEventReceiverActivity"    android:label="YOUR APPLICATION NAME - This appears in the permission popup"    android:theme="@style/Theme.Transparent"     android:noHistory="true"    android:excludeFromRecents="true"    android:taskAffinity="com.example.taskAffinityUsbEventReceiver"    android:process=":UsbEventReceiverActivityProcess"    android:exported="false"    >        <intent-filter>        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />    </intent-filter>    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />  </activity>

(I have a complex task/process layout in my service, YMMV in that area).

I defined the activity like this:

public class UsbEventReceiverActivity extends Activity{       public static final String ACTION_USB_DEVICE_ATTACHED = "com.example.ACTION_USB_DEVICE_ATTACHED";    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);    }    @Override    protected void onResume()    {        super.onResume();        Intent intent = getIntent();        if (intent != null)        {            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED))            {                Parcelable usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);                // Create a new intent and put the usb device in as an extra                Intent broadcastIntent = new Intent(ACTION_USB_DEVICE_ATTACHED);                broadcastIntent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice);                // Broadcast this event so we can receive it                sendBroadcast(broadcastIntent);            }        }        // Close the activity        finish();    }}

And the last piece of the puzzle, the transparent theme (I'm not sure but you could probably use the built in android translucent theme) - res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>      <resources>      <style name="Theme.Transparent" parent="android:Theme">        <item name="android:windowIsTranslucent">true</item>        <item name="android:windowBackground">@android:color/transparent</item>        <item name="android:windowContentOverlay">@null</item>        <item name="android:windowNoTitle">true</item>        <item name="android:windowIsFloating">true</item>        <item name="android:backgroundDimEnabled">false</item>        <item name="android:windowAnimationStyle">@null</item>    </style>  </resources>  


Late but i hope to help. Official android docs says "When users connect a device that matches your device filter, the system presents them with a dialog that asks if they want to start your application. If users accept, your application automatically has permission to access the device until the device is disconnected.". If you also check box to remember device, permission is granted until app uninstalls or data is deleted trough app manager.

So you must do:

  1. Add intent-filter as Wayne says, (and delete all about permissions in your main activity).
  2. Install app and CLOSE IT.
  3. Unplug and plug your usb.
  4. Accept permmission and check box to remember device.
  5. Enjoy.