Ich habe die MDM-App für Eltern, um Kindergeräte zu steuern, und sie verwendet die Berechtigung SYSTEM_ALERT_WINDOW
, um Warnungen auf dem Gerät des Kindes anzuzeigen, wenn eine verbotene Aktion ausgeführt wurde.
Auf Geräten M + während der Installation überprüft die App die Berechtigung mit dieser Methode:
Wenn diese Methode false
zurückgibt, öffnet die App den Systemdialog, in dem der Benutzer die Berechtigung erteilen kann:
Wenn Sie in Android O die Berechtigung erteilen und durch Drücken der Zurück-Taste zur App zurückkehren, gibt die Methode canDrawOverlays()
immer noch false
zurück, bis der Benutzer die App nicht schließt und öffnet oder wählen Sie es im letzten App-Dialog. Ich habe es auf der neuesten Version des virtuellen Geräts mit Android O in Android Studio getestet, weil ich kein echtes Gerät habe.
Ich habe ein wenig recherchiert und zusätzlich die Berechtigung mit AppOpsManager überprüft:
%Vor%Und so:
canDrawOverlays()
gibt false
zurück) wenn der Benutzer canDrawOverlays()
gibt false
zurück) canDrawOverlays()
gibt true
) Bitte, kann mir jemand dieses Verhalten erklären? Kann ich mich auf mode == 1
der Operation "android:system_alert_window"
verlassen und davon ausgehen, dass der Benutzer die Berechtigung erteilt hat?
Ich habe diese Probleme auch mit checkOp gefunden. In meinem Fall habe ich den Fluss, der erlaubt, auf Einstellungen nur umzuleiten, wenn die Erlaubnis nicht eingestellt wird. Und die AppOps wird nur beim Weiterleiten an Einstellungen festgelegt.
Angenommen AppOps Callback wird nur aufgerufen, wenn sich etwas geändert hat und es nur einen Schalter gibt, der geändert werden kann. Das heißt, wenn ein Rückruf aufgerufen wird, muss der Benutzer die Berechtigung erteilen.
%Vor% Nachdem die App wiederhergestellt wurde, hat die Überprüfung mit canDrawOverlays()
für mich funktioniert. Natürlich starte ich die App neu und überprüfe, ob die Erlaubnis über den Standardweg erteilt wurde.
Es ist definitiv keine perfekte Lösung, aber es sollte funktionieren, bis wir mehr von Google wissen.
BEARBEITEN: Ich fragte Google: Ссылка
EDIT 2: Google behebt dies. Aber es scheint, dass die Android O-Version immer noch betroffen sein wird.
Ich stieß auf das gleiche Problem. Ich verwende einen Workaround, der versucht, ein unsichtbares Overlay hinzuzufügen. Wenn eine Ausnahme ausgelöst wird, wird die Berechtigung nicht erteilt. Es ist vielleicht nicht die beste Lösung, aber es funktioniert. Ich kann Ihnen nichts über die AppOps-Lösung erzählen, aber es sieht zuverlässig aus.
%Vor%In meinem Fall habe ich die API-Ebene & lt; Oreo und die unsichtbare Überlagerungsmethode in Ch4t4's Antwort funktioniert nicht, da es keine Ausnahme auslöst.
Bei der obigen Antwort von l0v3 und der Notwendigkeit, den Benutzer davor zu schützen, die Berechtigung mehrmals zu wechseln, habe ich den folgenden Code verwendet (Android-Versionsprüfungen wurden weggelassen):
In der Aktivität / Fragment:
%Vor%Um die Berechtigung in der Aktivität / dem Fragment anzufordern:
%Vor% Und in onActivityResult
Um zu verhindern, dass Ihre Aktivität im Hintergrund zerstört wird, in onCreate
:
und intern onDestroy
, stopWatchingMode
sollten aufgerufen werden, wenn onOpChangedListener
nicht null ist, ähnlich wie onActivityResult
oben.
Es ist wichtig zu beachten, dass das System ab der aktuellen Implementierung (Android O) registrierte Listener vor dem Zurückrufen nicht de-duplizieren wird. Die Registrierung von startWatchingMode(ops, packageName, listener)
führt dazu, dass der Listener entweder für übereinstimmende Operationen oder den übereinstimmenden Paketnamen aufgerufen wird und für den Fall, dass beide übereinstimmen, zweimal aufgerufen wird. Daher wird der Paketname oben auf null gesetzt, um den doppelten Aufruf zu vermeiden. Wenn Sie den Listener mehrmals registrieren, ohne die Registrierung von stopWatchingMode
aufzuheben, wird der Listener mehrere Male aufgerufen - dies gilt auch für die gesamten Lebenszyklen der Aktivität destroy-create.
Alternativ zu den obigen Schritten können Sie eine Verzögerung von etwa 1 Sekunde vor dem Aufruf von Settings.canDrawOverlays(context)
festlegen. Der Wert der Verzögerung hängt jedoch vom Gerät ab und ist möglicherweise nicht zuverlässig. (Referenz: Ссылка )
Tatsächlich gibt es unter Android 8.0 true
zurück, aber es gibt Catch, es wird nur zurückgegeben, wenn Sie 5 bis 15 Sekunden warten und erneut nach Overlay-Berechtigung mit Settings.canDrawOverlays(context)
Methode suchen.
Sie müssen also dem Benutzer eine ProgressDialog
mit einer Fehlermeldung anzeigen und eine CountDownTimer
ausführen, um mit Settings.canDrawOverlays(context)
in onTick
method nach Overlay-Berechtigungen zu suchen.
Bitte schauen Sie sich einen Beispielcode aus einem Fragment an:
%Vor%Tags und Links android permissions