22 votes

Comment empêcher Android de demander la permission avant d'autoriser l'accès à un périphérique USB ?

J'ai une application fonctionnant sur une tablette Android sans nom rootée fonctionnant sous ICS 4.0.3 qui contrôle un périphérique USB via l'interface en mode hôte USB. Le fichier Android.hardware.usb.host.xml est présent dans /system/etc/permissions et tout fonctionne à merveille. Sauf que...

Lorsque je lance l'application pour la première fois après un redémarrage et que je branche le périphérique USB, j'obtiens une fenêtre popup indiquant "Allow the app APPNAME to access the USB device ? [] Utiliser par défaut pour ce périphérique USB. Cancel OK" et je dois appuyer sur OK avant qu'elle puisse commencer à utiliser le périphérique.

Je dois désactiver la confirmation de l'utilisateur pour que l'application puisse utiliser le dispositif immédiatement. Comment dois-je m'y prendre ? J'ai reçu quelques suggestions concernant l'utilisation d'un générateur de touches pour simuler l'utilisateur qui appuie sur le bouton à l'écran, mais je préférerais éviter ce genre d'approche et faire en sorte que la demande de confirmation ne se produise pas.

Je ne peux probablement pas obtenir du fournisseur qu'il me construise un noyau personnalisé, mais je devrais pouvoir obtenir d'eux la clé de signature du firmware pour que je puisse signer mon application comme une application système, si cela peut aider.

Un problème connexe : cocher la case "Utiliser par défaut pour ce périphérique USB" ne semble pas aider - si je débranche et rebranche le périphérique, je reçois à nouveau la demande de confirmation. J'ai remarqué dans cette situation que le numéro du périphérique dans /dev/bus/usb/001/ change à chaque fois que je débranche et rebranche (001, 002, 003 etc.) ce qui explique peut-être ce problème particulier.

0 votes

Que se passe-t-il si vous déployez l'application dans /system/app ? Vous pouvez essayer avec et sans signature du système. J'écris ce commentaire parce que (a) je ne l'ai pas essayé et (b) je ne sais pas si ce modèle de déploiement est disponible pour vous.

10voto

GalacticCowboy Points 8185

Cette question et cette réponse sont essentiellement une copie de
https://stackoverflow.com/a/15151075/588476
Voir le lien ci-dessus pour un exemple de programme et une discussion plus approfondie.

Pour autant que je sache, il y a deux façons de faire apparaître la boîte d'autorisation USB :

  1. Demandez la permission explicitement à votre application en utilisant UsbManager.requestPermission(...)
  2. Enregistrez un filtre d'intention sur votre accessoire et laissez le système demander l'autorisation lorsque le dispositif est fixé.

Dans le cas du point 1, j'ai constaté que la case à cocher de la fenêtre contextuelle permettant de se souvenir de l'autorisation n'a aucun effet.

Pour ma part, j'ai supprimé tout le code lié aux autorisations de mon logiciel et j'ai simplement placé le filtre d'intention dans mon manifeste. Lorsque le périphérique USB est branché, si la permission n'a pas déjà été accordée, la boîte de permission USB s'affiche. Si l'utilisateur clique sur OK sans cocher la case remember, la boîte s'affichera à nouveau lors de la prochaine connexion du périphérique. En revanche, si l'utilisateur coche la case et clique sur OK, la boîte ne devrait plus jamais s'afficher (sauf si le logiciel est désinstallé puis réinstallé).

Je ne suis pas sûr qu'il y ait un bogue quelque part lié au fait que votre périphérique s'affiche sous le nom de /dev/bus/usb/001, puis 002, etc. Indiquez-moi si vous utilisez le filtre d'intention, car sans cela, la case à cocher " se souvenir " n'aura aucun effet.

Je ne connais aucun moyen d'éviter complètement la fenêtre d'autorisation. Je pense qu'il n'y a aucun moyen de le faire sans creuser dans le code Android comme vous l'avez dit.

1 votes

Vous êtes sûr ? Je vois toujours la demande d'autorisation lorsque l'appareil est débranché et rebranché. Ce comportement est conforme à la documentation de developer.Android.com/guide/topics/connectivité/usb/host.html . La section "Utilisation d'un filtre d'intention" indique que "Si les utilisateurs acceptent, votre application a automatiquement la permission d'accéder à l'appareil jusqu'à ce que celui-ci soit déconnecté".

0 votes

Je ne peux me porter garant que pour la Nexus 7, le Galaxy S3 et le Galaxy Note. Sur ces appareils, je ne dois accepter l'autorisation qu'une seule fois (l'appareil Android fonctionne en mode hôte), à condition d'activer la case à cocher pour mémoriser la décision. Quel appareil/version d'Android utilisez-vous ? J'ai l'impression qu'il s'agit d'un appareil personnalisé ou d'origine ?

0 votes

Il s'agit d'une tablette OEM de 7 pouces basée sur le SOM WonderMedia WM8850-mid et fonctionnant sous leur version d'Android 4.0.3.

8voto

Rob Pridham Points 181

Suite à mon commentaire, j'ai jeté un coup d'œil au code Android sous-jacent.

J'ai une réponse possible, mais avec pas moins de quatre réserves et obstacles majeurs :

  1. Je ne l'ai pas encore essayé, car je n'ai pas de périphérique USB approprié sous la main.
  2. Vous avez besoin d'une nouvelle permission
  3. L'autorisation nécessite que vous soyez une application système
  4. Le code nécessite l'accès à quelque chose qui n'est pas dans l'API publique.

Oubliez cela si vous déployez des applications post-marché ordinaires !

La première condition préalable est que vous ayez la MANAGE_USB permission. Cela est décrit aquí .

Cependant, les conditions préalables à cela sont que vous signiez avec la clé du système et que vous installiez votre application dans /system/app.

Quoi qu'il en soit, si vous êtes d'accord avec ça, voici un peu de code :

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

mDevice est l'appareil d'avant.

uid est l'UID de votre propre application et vous pouvez le consulter. La première réponse donne un exemple de la façon de procéder. aquí .

Tout va bien ? Non. ServiceManager es android.os.ServiceManager et n'est donc pas une API publique. Dans cet exemple, c'est votre façon de mettre la main sur l IUsbManager service (il peut y avoir d'autres itinéraires). Maintenant, se déplacer que dépasse le cadre de ma réponse ; autrefois, vous pouviez utiliser la réflexion, mais je ne sais pas si c'est encore possible.

Après toutes ces manigances, il semble que vous n'ayez plus besoin de demander la permission, et si vous le faites, elle reviendra immédiatement sans dialogue.

0 votes

Sans signer je forge cette instruction ?

androidalle.com

AndroidAlle est une communauté de androiders où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X