So verhindern Sie, dass Android um Erlaubnis fragt, bevor Sie den Zugriff auf ein USB-Gerät zulassen

19

Ich habe eine Anwendung, die auf einem gerooteten No-Name-Android-Tablet mit ICS 4.0.3 ausgeführt wird und ein USB-Gerät über die USB-Hostmodus-Schnittstelle steuert. Die Datei android.hardware.usb.host.xml befindet sich in / system / etc / permissions und alles funktioniert wunderbar. Außer...

Wenn ich die App nach einem Neustart zum ersten Mal ausführe und dann das USB-Gerät anschließe, wird ein Popup-Fenster mit der Meldung "APPNAME auf das USB-Gerät zugreifen lassen? [] Standardmäßig für dieses USB-Gerät verwenden. Abbrechen OK" und angezeigt Ich muss auf OK tippen, bevor das Gerät verwendet werden kann.

Ich muss die Benutzerbestätigung deaktivieren, damit die App das Gerät sofort verwenden kann. Wie mache ich das? Ich scheine einige Vorschläge zur Verwendung eines Tastendruckgenerators zu haben, um zu simulieren, dass der Benutzer auf die Schaltfläche auf dem Bildschirm tippt, aber ich würde es vorziehen, eine solche Vorgehensweise zu vermeiden und die Dinge so einzurichten, dass die Bestätigungsanforderung einfach nicht erfolgt.

Ich kann den Lieferanten wahrscheinlich nicht dazu bringen, einen benutzerdefinierten Kernel-Build für mich zu erstellen, aber ich sollte in der Lage sein, den Firmware-Signaturschlüssel von ihnen zu erhalten, damit ich meine App als System-App signieren kann, wenn dies hilfreich ist.

Ein damit verbundenes Problem: Das Aktivieren des Kontrollkästchens "Standardmäßig für dieses USB-Gerät verwenden" scheint nicht zu helfen. Wenn ich das Gerät aus und wieder einstecke, wird die Bestätigungsaufforderung erneut angezeigt. In dieser Situation ist mir aufgefallen, dass sich die Gerätenummer in / dev / bus / usb / 001 / jedes Mal ändert, wenn ich den Stecker aus der Steckdose ziehe und wieder einstecke (001, 002, 003 usw.). Dies erklärt möglicherweise dieses spezielle Problem.

kbro
quelle
Was passiert, wenn Sie die App in / system / app bereitstellen? Sie können dies mit und ohne Systemsignierung versuchen. Ich schreibe dies als Kommentar, weil (a) ich es nicht ausprobiert habe und (b) ich nicht weiß, ob dieses Bereitstellungsmodell für Sie verfügbar ist.
Rob Pridham

Antworten:

10

Diese Frage und Antwort ist im Grunde ein Duplikat von
/programming//a/15151075/588476
. Unter dem obigen Link finden Sie ein Beispielprogramm und ausführlichere Informationen.

Soweit ich weiß, gibt es zwei Möglichkeiten, das Popup der USB-Berechtigungsbox abzurufen:

  1. Fordern Sie mit UsbManager.requestPermission (...) explizit eine Genehmigung für Ihre Anwendung an.
  2. Registrieren Sie einen Vorsatzfilter in Ihrem Zubehör und lassen Sie das System nachfragen, wenn das Gerät angeschlossen ist

Im Fall von 1 habe ich festgestellt, dass das Kontrollkästchen im Popup zur Erinnerung an die Erlaubnis keine Auswirkung hat.

Für mich habe ich den gesamten Code für Berechtigungen aus meiner Software entfernt und einfach den Intent-Filter in mein Manifest eingefügt. Wenn das USB-Gerät angeschlossen ist und noch keine Berechtigung erhalten hat, wird das USB-Berechtigungsfeld angezeigt. Wenn der Benutzer auf OK klickt, ohne das Kontrollkästchen zu aktivieren, wird das Kontrollkästchen beim nächsten Anschließen des Geräts erneut angezeigt. Wenn der Benutzer das Kontrollkästchen aktiviert und auf OK drückt, sollte das Kontrollkästchen nie wieder angezeigt werden (es sei denn, die Software wird deinstalliert und anschließend neu installiert).

Ich bin mir nicht sicher, ob irgendwo ein Fehler in Bezug auf Ihr Gerät aufgetreten ist, der als / dev / bus / usb / 001 und dann als 002 usw. angezeigt wird. Lassen Sie mich wissen, ob Sie den Intent-Filter verwenden nichts tun.

Ich kenne keine Möglichkeit, die Erlaubnis Popup insgesamt zu vermeiden. Ich vermute, es gibt keine Möglichkeit, es zu tun, ohne in den Android-Code zu graben, wie Sie gesagt haben.

Wayne Uroda
quelle
1
Bist du sicher? Ich sehe immer noch die Erlaubnisanfrage, wenn das Gerät vom Stromnetz getrennt und wieder verbunden wird. Dieses Verhalten stimmt mit der Dokumentation in developer.android.com/guide/topics/connectivity/usb/host.html überein . Der Abschnitt "Verwenden eines Absichtsfilters" lautet "Wenn Benutzer zustimmen, hat Ihre Anwendung automatisch die Berechtigung, auf das Gerät zuzugreifen, bis die Verbindung zum Gerät getrennt wird"
kbro
Ich kann nur für das Nexus 7, Galaxy S3 und Galaxy Note bürgen. Auf diesen Geräten muss ich die Erlaubnis nur einmal akzeptieren (das Android-Gerät wird im Host-Modus ausgeführt) - vorausgesetzt, ich aktiviere das Kontrollkästchen, um mich an die Entscheidung zu erinnern. Welches Gerät / welche Android-Version verwenden Sie? Ich habe das Gefühl, dass es sich um ein benutzerdefiniertes / OEM-Gerät handelt.
Wayne Uroda
Es handelt sich um ein OEM-7-Zoll-Tablet, das auf dem WonderMedia WM8850-mid SOM basiert und auf Android 4.0.3 basiert.
Kbro
Absichtsfilter funktionieren nur für die aktuelle Boot-Sitzung. Ja, ich schließe ein USB-Gerät an mein Telefon an und es gewährt automatisch die Erlaubnis
user924
7

Nach meinem Kommentar habe ich mir den zugrunde liegenden Android-Code angesehen.

Ich habe eine mögliche Antwort, aber nicht weniger als vier wichtige Vorbehalte und Hindernisse:

  1. Ich habe es nicht ausprobiert, weil ich keine geeigneten USB-Geräte zur Hand habe.
  2. Sie benötigen eine neue Erlaubnis
  3. Die Berechtigung setzt voraus, dass Sie eine System-App sind
  4. Der Code erfordert Zugriff auf etwas, das nicht in der öffentlichen API enthalten ist

Vergessen Sie dies, wenn Sie normale After-Market-Apps bereitstellen!

Die erste Voraussetzung ist, dass Sie die MANAGE_USBErlaubnis haben. Das wird hier beschrieben .

Voraussetzung dafür ist jedoch wiederum, dass Sie mit dem Systemschlüssel signieren und Ihre App in / system / app installieren.

Wie auch immer, wenn Sie damit einverstanden sind, hier ist ein Code:

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

mDevice ist das Gerät von vor.

uidist die UID Ihrer eigenen App und das können Sie nachschlagen. Ein Beispiel dafür ist die erste Antwort hier .

Alles gut? No. ServiceManagerist android.os.ServiceManagerund ist daher keine öffentliche API. In diesem Beispiel ist dies Ihr Weg, um den IUsbManagerService in den Griff zu bekommen (es kann auch andere Routen geben). Nun, um immer das sprengt den Rahmen meiner Antwort; Früher konnte man Überlegung gebrauchen, aber ich weiß nicht, ob man das noch kann.

Nach all diesen Spielereien scheint es, als müssten Sie keine Erlaubnis mehr anfordern, und wenn Sie dies tun, wird es sofort ohne Dialog zurückkehren.

Rob Pridham
quelle