web-dev-qa-db-fra.com

Suppression des fenêtres contextuelles d'accès aux périphériques USB?

Lorsqu'un périphérique USB est connecté à la Android, une fenêtre contextuelle apparaît demandant l'autorisation de l'utilisateur. Je souhaite supprimer cela car le client ne le souhaite pas. Comment dois-je procéder? ?

Dans le code:

UsbManager.requestpermission(); 

est appelé pour donner au périphérique USB un accès temporaire.

Cela ouvre une fenêtre contextuelle. Comment supprimer la fenêtre contextuelle ou accorder l'accès à l'utilisateur par défaut?

46
venkat

Lorsque vous demandez l'autorisation à l'intérieur de votre application, il semble que la case à cocher "utiliser par défaut pour ce périphérique USB" ne fait rien (je ne sais pas pourquoi cette case à cocher apparaît même dans cette fenêtre contextuelle.

Au lieu de cela, vous devez enregistrer un gestionnaire d'intention pour votre activité dans le manifeste:

<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>

Vous devez également créer un fichier de filtre dans vos ressources xml, par exemple res/xml/usb_device_filter:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="26214" product-id="26214" />
</resources>

L'identifiant du fournisseur et l'ID du produit doivent être indiqués en décimal - au-dessus du VID et du PID sont 0x6666.

Ce que j'ai donné ci-dessus fonctionne également pour un accessoire USB (c'est-à-dire où l'accessoire est l'hôte USB et le Android est le périphérique) - dans ce cas, le filtre d'intention doit s'enregistrer

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

et vous devez également inclure le filtre de métadonnées exactement de la même manière.

Voir http://developer.Android.com/guide/topics/connectivity/usb/accessory.html et recherchez la section "Utilisation d'un filtre d'intention".

[~ # ~] modifier [~ # ~]

Pour conclure - si vous enregistrez le filtre d'intention par rapport à votre activité, la fenêtre d'autorisation USB s'affiche immédiatement lorsque le périphérique/accessoire USB est connecté. Si l'utilisateur coche la case "utiliser par défaut pour ce périphérique USB" et accorde ensuite l'autorisation, cela sera mémorisé et la boîte de dialogue d'autorisation ne s'affichera plus (sauf si l'application est désinstallée ou si l'utilisateur efface l'action par défaut du gestionnaire d'application ).

J'ai mis ici un tout petit projet d'exemple qui fonctionne:

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

Vous devrez éditer res/xml/usb_device_filter.xml, mais sinon cela devrait vous permettre de le tester très rapidement.

Pour les services ...

Il semble qu'un service ne puisse pas recevoir les intentions USB. J'ai contourné cela en faisant une activité cachée qui rediffusait ensuite les intentions.

Je le définis dans mon manifeste comme ceci:

<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>

(J'ai une disposition complexe de tâches/processus dans mon service, YMMV dans ce domaine).

J'ai défini l'activité comme ceci:

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();
    }
}

Et la dernière pièce du puzzle, le thème transparent (je ne suis pas sûr mais vous pourriez probablement utiliser le thème intégré Android translucide) - 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>  
88
Wayne Uroda