Demnach: http://developer.android.com/preview/features/runtime-permissions.html#coding Eine App kann nach Laufzeitberechtigungen suchen und Berechtigungen anfordern, wenn diese noch nicht erteilt wurde. Der folgende Dialog wird dann angezeigt:
Falls der Benutzer eine wichtige Berechtigung ablehnt, sollte in einer App eine Erklärung angezeigt werden, warum die Berechtigung benötigt wird und welche Auswirkungen das Ablehnen hat. Dieser Dialog hat zwei Möglichkeiten:
- erneut versuchen (Erlaubnis wird erneut angefordert)
- verweigern (App funktioniert ohne diese Erlaubnis).
Wenn der Benutzer dies Never ask again
jedoch überprüft , sollte der zweite Dialog mit der Erklärung nicht angezeigt werden, insbesondere wenn der Benutzer bereits einmal abgelehnt hat. Die Frage ist nun: Woher weiß meine App, ob der Benutzer das überprüft hat Never ask again
? IMO onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
gibt mir diese Informationen nicht.
Eine zweite Frage wäre: Hat Google vor, eine benutzerdefinierte Nachricht in den Berechtigungsdialog aufzunehmen, die erklärt, warum die App die Berechtigung benötigt? Auf diese Weise würde es niemals einen zweiten Dialog geben, der sicherlich zu einem besseren UX führen würde.
quelle
Antworten:
Die Entwicklervorschau 2 enthält einige Änderungen an der Anforderung von Berechtigungen durch die App (siehe auch http://developer.android.com/preview/support.html#preview2-notes ).
Der erste Dialog sieht nun so aus:
Es gibt kein Kontrollkästchen "Nie wieder anzeigen" (im Gegensatz zur Entwicklervorschau 1). Wenn der Benutzer die Berechtigung verweigert und die Berechtigung für die App wesentlich ist, kann ein weiterer Dialog angezeigt werden, in dem der Grund erläutert wird, warum die App diese Berechtigung anfordert, z. B.:
Wenn der Benutzer erneut ablehnt, sollte die App entweder heruntergefahren werden, wenn diese Berechtigung unbedingt erforderlich ist, oder mit eingeschränkter Funktionalität weiter ausgeführt werden. Wenn der Benutzer es erneut überprüft (und einen erneuten Versuch auswählt), wird die Berechtigung erneut angefordert. Diesmal sieht die Eingabeaufforderung folgendermaßen aus:
Beim zweiten Mal wird das Kontrollkästchen "Nie wieder fragen" angezeigt. Wenn der Benutzer erneut ablehnt und das Kontrollkästchen aktiviert ist, sollte nichts mehr passieren. Ob das Kontrollkästchen aktiviert ist oder nicht, kann mithilfe von Activity.shouldShowRequestPermissionRationale (String) ermittelt werden, z. B.: Z.
Das steht in der Android-Dokumentation ( https://developer.android.com/training/permissions/requesting.html ):
Um festzustellen , ob der Benutzer mit "Nie wieder fragen" abgelehnt hat, können Sie die Methode shouldShowRequestPermissionRationale in Ihrem onRequestPermissionsResult erneut überprüfen, wenn der Benutzer die Berechtigung nicht erteilt hat.
Sie können Ihre App-Einstellung mit folgendem Code öffnen:
Es gibt keine Möglichkeit, den Benutzer direkt zur Autorisierungsseite zu senden.
quelle
Sie können
shouldShowRequestPermissionRationale()
Ihre eincheckenonRequestPermissionsResult()
.https://youtu.be/C8lUdPVSzDk?t=2m23s
Überprüfen Sie, ob die Berechtigung erteilt wurde oder nicht
onRequestPermissionsResult()
. Wenn nicht, dann überprüfenshouldShowRequestPermissionRationale()
.true
wird, geben Sie eine Erklärung an, warum diese bestimmte Berechtigung erforderlich ist. Dann je nach Wahl des Benutzers wiederrequestPermissions()
.false
, wird eine Fehlermeldung angezeigt, dass die Berechtigung nicht erteilt wurde und die App nicht weiter fortfahren kann oder eine bestimmte Funktion deaktiviert ist.Unten finden Sie einen Beispielcode.
Anscheinend macht Google Maps genau dies für die Standortberechtigung.
quelle
Hier ist eine nette und einfache Methode, um den aktuellen Berechtigungsstatus zu überprüfen:
Vorsichtsmaßnahme: Gibt BLOCKED_OR_NEVER_ASKED beim ersten Start der App zurück, bevor der Benutzer die Berechtigung über die Benutzeraufforderung akzeptiert / verweigert hat (auf SDK 23+ Geräten).
Aktualisieren:
Die Android-Unterstützungsbibliothek scheint nun auch eine sehr ähnliche Klasse zu haben, die eine
android.support.v4.content.PermissionChecker
enthält,checkSelfPermission()
die Folgendes zurückgibt:quelle
BLOCKED_OR_NEVER_ASKED
wenn die Berechtigung noch nicht angefordert wurde.android.content.pm
definiert bereitsPERMISSION_GRANTED = 0
undPERMISSION_DENIED = -1
. Vielleicht setzenBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
oder so?Sobald der Benutzer "Nicht erneut fragen" markiert hat, kann die Frage nicht mehr angezeigt werden. Dem Benutzer kann jedoch erklärt werden, dass er zuvor die Berechtigung verweigert hat und in den Einstellungen die Berechtigung erteilen muss. Und verweisen Sie ihn mit dem folgenden Code auf die Einstellungen:
quelle
Kann für jemanden nützlich sein: -
Was mir aufgefallen ist, ist, dass beim Aktivieren des Flags shouldShowRequestPermissionRationale () in der Rückrufmethode onRequestPermissionsResult () nur zwei Zustände angezeigt werden .
Status 1: -Return true: - Jedes Mal, wenn der Benutzer auf Verweigern von Berechtigungen klickt (einschließlich des ersten Males).
Status 2: - Gibt false zurück: - Wenn der Benutzer "Nie wieder fragen" auswählt.
Link zum detaillierten Arbeitsbeispiel
quelle
onRequestPermissionsResult
, nicht wenn Sie tatsächlich die Erlaubnis anfordern.Sie können bestimmen , es durch Prüfen , ob die Erlaubnis Begründung in der gezeigt werden soll ,
onRequestPermissionsResult()
Callback - Methode. Wenn Sie einen Berechtigungssatz finden , der Sie nie wieder fragen kann, können Sie Benutzer auffordern, Berechtigungen aus den Einstellungen zu erteilen.Meine vollständige Implementierung wäre wie folgt. Es funktioniert sowohl für Einzel- als auch für Mehrfachberechtigungsanforderungen . Verwenden Sie Folgendes oder direkt meine Bibliothek.
quelle
Wenn Sie alle "Zustände" erkennen möchten (erstmalig abgelehnt, nur abgelehnt, nur mit "Nie wieder fragen" verweigert oder dauerhaft abgelehnt), können Sie Folgendes tun:
Erstellen Sie 2 Boolesche Werte
Stellen Sie den ersten ein, bevor Sie um Erlaubnis bitten:
Legen Sie die zweite in Ihrer onRequestPermissionsResult-Methode fest:
Verwenden Sie die folgende "Tabelle", um alles zu tun, was Sie in onRequestPermissionsResult () benötigen (nachdem Sie überprüft haben, dass Sie noch nicht über die Berechtigung verfügen):
quelle
// TRUE FALSE
tritt auch auf, wenn der Benutzer eine Berechtigung zulässt, nachdem er sie zuvor verweigert hat.Ich hatte das gleiche Problem und habe es herausgefunden. Um das Leben viel einfacher zu machen, habe ich eine util-Klasse geschrieben, um Laufzeitberechtigungen zu verarbeiten.
Die PreferenceUtil- Methoden lauten wie folgt.
Jetzt müssen Sie nur noch die Methode * checkPermission * mit den richtigen Argumenten verwenden.
Hier ist ein Beispiel,
Wenn der Benutzer Nie wieder fragen aktiviert ist , erhalten Sie einen Rückruf auf onPermissionDisabled .
Viel Spaß beim Codieren :)
quelle
shouldShowRequestPermissionRationale
zu umgehen und die an den Benutzer gesendete Anforderung zu speichern. Ich hatte die gleiche Idee und fand Ihre Antwort. Netter Job MannVollständige Erklärung für jeden Fall der Erlaubnis
quelle
Eine nützliche Funktion, um festzustellen, ob eine beliebige Berechtigung für die Anforderung gesperrt wurde (in Kotlin):
Um dies zu verwenden, müssen Sie einen Booleschen Wert für gemeinsame Einstellungen mit dem Namen Ihrer gewünschten Berechtigung (z. B.
android.Manifest.permission.READ_PHONE_STATE
) festlegen,true
wenn Sie zum ersten Mal eine Berechtigung anfordern.Erläuterung:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
da ein Teil des Codes möglicherweise nur auf API-Ebene 23+ ausgeführt wird.ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
Zur Überprüfung haben wir noch keine Erlaubnis.!activity.shouldShowRequestPermissionRationale(permission)
um zu überprüfen, ob der Benutzer die App abgelehnt hat und erneut fragt. Aufgrund von Macken dieser Funktion ist auch die folgende Zeile erforderlich.PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
Dies wird verwendet (zusammen mit dem Setzen des Werts auf true bei der ersten Berechtigungsanforderung), um zwischen den Zuständen "Nie gefragt" und "Nie wieder fragen" zu unterscheiden, da die vorherige Zeile diese Informationen nicht zurückgibt.quelle
Mit der Methode shouldShowRequestPermissionRationale () kann überprüft werden, ob der Benutzer die Option "Nie wieder gefragt" ausgewählt und die Berechtigung verweigert hat. Es gibt viele Codebeispiele, daher würde ich lieber erklären, wie man es für einen solchen Zweck verwendet, da ich denke, dass sein Name und seine Implementierung dies komplizierter machen, als es tatsächlich ist.
Wie unter Anfordern von Berechtigungen zur Laufzeit erläutert , gibt diese Methode true zurück, wenn die Option 'nie wieder fragen' sichtbar ist, andernfalls false. Daher wird beim ersten Anzeigen eines Dialogfelds false zurückgegeben. Ab dem zweiten Mal wird true zurückgegeben. Wenn der Benutzer die Berechtigung zur Auswahl der Option verweigert, wird an diesem Punkt erneut false zurückgegeben.
Um einen solchen Fall zu erkennen, können Sie entweder die Sequenz false-true-false erkennen oder (einfacher) ein Flag verwenden, das die anfängliche Zeit verfolgt, zu der der Dialog angezeigt wird. Danach gibt diese Methode entweder true oder false zurück, wobei Sie mit false erkennen können, wann die Option ausgewählt ist.
quelle
Bitte werfen Sie für diese Lösung keine Steine auf mich.
Das funktioniert aber ist ein bisschen "hacky".
Wenn Sie anrufen
requestPermissions
, registrieren Sie die aktuelle Uhrzeit.Dann in
onRequestPermissionsResult
Wenn das Ergebnis nicht gewährt wird, überprüfen Sie die Uhrzeit erneut.
Da der Benutzer möglicherweise nicht so schnell auf die Schaltfläche "Verweigern" klicken kann, wissen wir, dass er "Nie wieder fragen" ausgewählt hat, da der Rückruf sofort erfolgt.
Verwendung auf eigenes Risiko.
quelle
Ich habe eine Abkürzung für die Berechtigungsanforderung in Android M geschrieben. Dieser Code behandelt auch die Abwärtskompatibilität mit älteren Android-Versionen.
Der gesamte hässliche Code wird in ein Fragment extrahiert, das sich an die Aktivität anfügt und von dieser löst, um die Berechtigungen anzufordern. Sie können
PermissionRequestManager
Folgendes verwenden:Schauen Sie sich das an: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
quelle
quelle
Probieren Sie diese einfache Berechtigungsbibliothek aus. Alle mit der Berechtigung verbundenen Vorgänge werden in drei einfachen Schritten ausgeführt. Das hat mir Zeit gespart. Sie können alle berechtigungsbezogenen Arbeiten in 15 Minuten beenden .
Es kann mit Verweigern umgehen, es kann mit Nie wieder fragen umgehen, es kann App-Einstellungen zur Erlaubnis aufrufen, es kann eine rationale Nachricht geben, es kann eine Verweigerungsnachricht geben, es kann eine Liste akzeptierter Berechtigungen geben, es kann eine Liste verweigerter Nachrichten geben Berechtigungen und etc.
https://github.com/ParkSangGwon/TedPermission
Schritt 1: Fügen Sie Ihre Abhängigkeit hinzu
Schritt 2: Fragen Sie nach Berechtigungen
Schritt 3: Berechtigungsantwort verarbeiten
quelle
Sie können hübsch zuhören.
Hörer
Hauptklasse zur Erlaubnis
Auf diese Weise verwendet
onRequestPermissionsResult in activity oder fragmnet überschreiben
quelle
Stattdessen erhalten Sie einen Rückruf
onRequestPermissionsResult()
als PERMISSION_DENIED, wenn Sie erneut um Erlaubnis bitten, während Sie in den falschen Zustand von fallenshouldShowRequestPermissionRationale()
Aus dem Android-Dokument:
Wenn das System den Benutzer auffordert, eine Berechtigung zu erteilen, hat der Benutzer die Möglichkeit, das System anzuweisen, diese Berechtigung nicht erneut anzufordern. In diesem Fall lehnt
requestPermissions()
das System die Anforderung jedes Mal sofort ab , wenn eine App diese Berechtigung erneut anfordert. Das System ruft IhreonRequestPermissionsResult()
Rückrufmethode auf und übergibt siePERMISSION_DENIED
genauso, wie wenn der Benutzer Ihre Anfrage erneut explizit abgelehnt hätte. Dies bedeutet, dass Sie beim AnrufrequestPermissions()
nicht davon ausgehen können, dass eine direkte Interaktion mit dem Benutzer stattgefunden hat.quelle
Mit der
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
Methode können Sie feststellen, ob nie gefragt aktiviert ist oder nicht.Weitere Informationen: Überprüfen Sie dies
Um nach mehreren Berechtigungen zu suchen, verwenden Sie:
EXPLAIN () -Methode
Der obige Code zeigt auch ein Dialogfeld an, in dem der Benutzer zum Bildschirm mit den App-Einstellungen weitergeleitet wird, von dem aus er die Berechtigung erteilen kann, wenn er die Schaltfläche Nie wieder fragen aktiviert hat.
quelle
Sie können verwenden
Innerhalb
Siehe das folgende Beispiel:
Überprüfen Sie, ob die Berechtigung vorliegt, wenn der Benutzer auf die Schaltfläche klickt:
Wenn der Benutzer das Berechtigungsdialogfeld beantwortet, gehen wir zu onRequestPermissionResult:
quelle
Ich möchte auch die Information erhalten, ob der Benutzer "Nie wieder fragen" ausgewählt hat oder nicht. Ich habe mit einer hässlich aussehenden Flagge eine „fast Lösung“ erreicht, aber bevor ich Ihnen sage, wie, werde ich Ihnen von meiner Motivation erzählen:
Ich möchte zunächst die Berechtigungsverweisfunktion anbieten. Wenn der Benutzer es verwendet und keine Rechte hat, erhält er entweder den 1. Dialog von oben oder sowohl den 2. als auch den 3. Dialog. Wenn der Benutzer "Nie wieder fragen" gewählt hat, möchte ich die Funktionalität deaktivieren und anders anzeigen. - Meine Aktion wird durch eine Spinner-Texteingabe ausgelöst. Ich möchte dem angezeigten Beschriftungstext auch '(Berechtigung widerrufen)' hinzufügen. Dies zeigt dem Benutzer: "Es gibt Funktionen, die ich jedoch aufgrund meiner Berechtigungseinstellungen nicht verwenden kann." Dies scheint jedoch nicht möglich zu sein, da ich nicht überprüfen kann, ob "Nie wieder fragen" gewählt wurde.
Ich bin zu einer Lösung gekommen, mit der ich leben kann, indem meine Funktionalität immer mit einer aktiven Berechtigungsprüfung aktiviert wurde. Bei einer negativen Antwort wird in onRequestPermissionsResult () eine Toast-Nachricht angezeigt, jedoch nur, wenn ich mein benutzerdefiniertes Begründungs-Popup nicht angezeigt habe. Wenn der Benutzer "Nie wieder fragen" gewählt hat, erhält er nur eine Toastnachricht. Wenn der Benutzer nicht "Nie wieder fragen" wählt, erhält er nur die benutzerdefinierte Begründung und das Popup "Berechtigungsanforderung" vom Betriebssystem, jedoch keinen Toast, da drei Benachrichtigungen hintereinander zu schmerzhaft wären.
quelle
Ich muss eine dynamische Berechtigung für die Kamera implementieren. Wo 3 mögliche Fälle auftreten: 1. Zulassen, 2. Verweigert, 3. Nicht erneut fragen.
quelle
Ausgehend von der obigen Antwort von mVck bestimmt die folgende Logik, ob "Nie wieder fragen" für eine bestimmte Berechtigungsanforderung überprüft wurde:
welches von unten extrahiert wird (für das vollständige Beispiel siehe diese Antwort )
quelle
Sie können das offizielle Android-Dokument App-Berechtigungen anfordern lesen
oder Sie können viele beliebte Android-Berechtigungsbibliotheken auf Github finden
quelle
Um die Frage genau zu beantworten: Was passiert, wenn der Benutzer "Nie wieder fragen" drückt?
Die überschriebene Methode / Funktion
Das GrantResult-Array wird als leer ausgegeben, sodass Sie dort möglicherweise etwas tun können. Aber nicht die beste Vorgehensweise.
Wie gehe ich mit "Nie wieder fragen" um?
Ich arbeite mit Fragment, für das die Berechtigung READ_EXTERNAL_STORAGE erforderlich war.
Die anderen Funktionen sind trivial.
quelle