Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

android - USB device access pop-up suppression?

When a USB device is connected to the Android tablet, a pop-up appears asking for user-permission. I want to suppress this as the client does not want it. How should I go about that?

In the code:

UsbManager.requestpermission(); 

is called to give the USB device temporary access.

This throws a pop-up. How do I suppress the pop-up or grant access to the user by default?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...