23

I have an application running on a rooted no-name Android tablet running ICS 4.0.3 that controls a USB device via the USB host mode interface. The android.hardware.usb.host.xml file is present in /system/etc/permissions and everything works wonderfully. Except...

When I run the app for the first time following a reboot and then plug in the USB device I get a popup window saying "Allow the app APPNAME to access the USB device? [] Use by default for this USB device. Cancel OK" and I have to tap OK before it can start using the device.

I need to turn off the user confirmation so that the app can use the device straight away. How do I do this? I've seem some suggestions about using a keypress generator to simulate the user tapping the button on the screen but I'd prefer to avoid that sort of approach and set things up so that the confirmation request simply doesn't happen.

I probably can't get the supplier to do a custom kernel build for me, but I should be able to get the firmware signing key from them so I can sign my app as a system app, if that will help.

One associated problem: ticking the "Use by default for this USB device" box doesn't appear to help - if I unplug and replug the device then I get the confirmation prompt again. I have noticed in this situation that the device number in /dev/bus/usb/001/ changes each time I unplug and replug (001, 002, 003 etc) which perhaps explains this particular problemette.

1
  • What happens if you deploy the app into /system/app? You can try this with and without system signing. I write this as a comment because (a) I haven't tried it, and (b) I don't know whether this deployment model is available to you. Commented Mar 8, 2013 at 15:23

2 Answers 2

11

This question and answer is basically a duplicate of
https://stackoverflow.com/a/15151075/588476
See the above link for an example program and more in depth discussion.

As far as I know, there are two ways to get the USB permission box popup:

  1. Request permission explicitly from your application using UsbManager.requestPermission(...)
  2. Register an intent-filter on your accessory and let the system ask for permission when the device is attached

In the case of 1 I have found that the checkbox on the popup to remember the permission has no effect.

For me, I removed all code related to permissions from my software and simply put the intent-filter in my manifest. When the USB device is plugged in, if it hasn't already been granted permission then the USB permission box will popup. If the user clicks OK without checking the remember box, then the box will popup again the next time the device is connected. However if the user checks the box and presses OK then the box should never display again (unless the software is uninstalled and then reinstalled).

I'm not sure if there is a bug somewhere related to your device showing up as /dev/bus/usb/001 and then 002 etc - let me know if you are using the intent-filter, as without that the remember checkbox will do nothing.

I do not know of any way that you can avoid the permission popup altogether. I suspect there is no way to do it without digging into the android code like you said.

4
  • 1
    Are you sure? I'm still seeing the permission request when the device is unplugged and reconnected. This behaviour is consistent with the documentation in developer.android.com/guide/topics/connectivity/usb/host.html. The "Using an intent filter" section says "If users accept, your application automatically has permission to access the device until the device is disconnected"
    – kbro
    Commented Mar 7, 2013 at 23:09
  • I can only vouch for the Nexus 7, Galaxy S3 and Galaxy Note, on those devices I only have to accept the permission once (the Android device is running in host mode) - provided I enable the checkbox to remember the decision. What device/version of android are you using, I get the feeling it is a custom/OEM device? Commented Mar 8, 2013 at 0:33
  • It's an OEM 7-inch tablet based on the WonderMedia WM8850-mid SOM running their flavour of Android 4.0.3.
    – kbro
    Commented Mar 8, 2013 at 7:01
  • Intent-filters are working only for the current boot session. Yes I plug a usb device to my phone and it grants permission automatically
    – user924
    Commented Aug 23, 2019 at 7:33
9

Further to my comment, I had a look into the underlying Android code.

I have a possible answer, but with no less than four major caveats and obstacles:

  1. I haven't tried it, because I don't have any suitable USB devices to hand.
  2. You need a new permission
  3. The permission requires that you are a system app
  4. The code requires access to something not in the public API

Forget about this if deploying ordinary after-market apps!

The first prerequisite is that you have the MANAGE_USB permission. That is described here.

However in turn the prerequisites for that are that you sign with the system key, and you install your app into /system/app.

Anyway, if you're OK with that, here's some code:

   IBinder b = ServiceManager.getService(USB_SERVICE);
   IUsbManager service = IUsbManager.Stub.asInterface(b);
   service.grantDevicePermission(mDevice, uid);

mDevice is the device from before.

uid is your own app's UID and you can look that up. An example of how to do that is the first answer here.

All good? No. ServiceManager is android.os.ServiceManager and thus isn't a public API. That, in this example, is your way to getting your hands on the IUsbManager service (there may be other routes). Now, getting around that is beyond the scope of my answer; in the old days you could use reflection, but I don't know if you still can.

After all of those shenanigans, it looks like you don't need to request permission any more, and if you do, it will return immediately with no dialog.

1
  • without signed i forge this instruction?
    – Fortran
    Commented Jan 7, 2021 at 19:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .