ActivityCompat.requestPermissions wird nicht angezeigt

73
if (ContextCompat.checkSelfPermission(RegisterActivity.this,      Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE_PERMISSION);

Ich versuche, diese Funktion auf Nexus 5 API 23 zu verwenden, und sie zeigt mir nur nicht das Dialogfeld, wie es soll, es tut einfach nichts. Was könnte das Problem verursachen? (Dieser Code befindet sich in der Java-Aktivität.) Ich habe versucht, meine minimale API auf 23 zu ändern und die requestPermissions () ohne ActivityCompat zu verwenden, aber es funktioniert immer noch nicht.

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
    applicationId "com.example.idanayzen.photomap"
    minSdkVersion 23
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:design:23.1.1'
}

und das Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.idanayzen.photomap">

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">


    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps" />
    <activity android:name=".RegisterActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".WrongPhoneNum"></activity>
</application>

</manifest>
Idan Ayzen
quelle
Übrigens habe ich bereits versucht, den String in "android.permission.READ_PHONE_STATE" zu ändern
Idan Ayzen
Ist die Erlaubnis gesperrt?
K.Sopheak

Antworten:

92

Hier ist ein Beispiel für die Verwendung von requestPermissions():

Definieren Sie zunächst die Berechtigung (wie in Ihrem Beitrag) im Manifest. Andernfalls wird Ihre Anfrage automatisch abgelehnt:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Definieren Sie als Nächstes in onRequestPermissionsResult () einen Wert für den Berechtigungsrückruf:

private final int REQUEST_PERMISSION_PHONE_STATE=1;

Hier ist der Code zum Aufrufen von requestPermissions ():

private void showPhoneStatePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.READ_PHONE_STATE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_PHONE_STATE)) {
            showExplanation("Permission Needed", "Rationale", Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        } else {
            requestPermission(Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION_PHONE_STATE);
        }
    } else {
        Toast.makeText(MainActivity.this, "Permission (already) Granted!", Toast.LENGTH_SHORT).show();
    }
}

Zunächst überprüfen Sie, ob Sie bereits über eine Berechtigung verfügen (denken Sie daran, dass der Benutzer die Berechtigung auch nach Erteilung der Berechtigung später in den App-Einstellungen widerrufen kann.)

Und schließlich überprüfen Sie auf diese Weise, ob Sie die Erlaubnis erhalten haben oder nicht:

@Override
public void onRequestPermissionsResult(
        int requestCode,
        String permissions[],
        int[] grantResults) {
    switch (requestCode) {
        case REQUEST_PERMISSION_PHONE_STATE:
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "Permission Granted!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
            }
    }
}

private void showExplanation(String title,
                             String message,
                             final String permission,
                             final int permissionRequestCode) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title)
            .setMessage(message)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    requestPermission(permission, permissionRequestCode);
                }
            });
    builder.create().show();
}

private void requestPermission(String permissionName, int permissionRequestCode) {
    ActivityCompat.requestPermissions(this,
            new String[]{permissionName}, permissionRequestCode);
}
NightSkyDev
quelle
16
Ist es nicht sinnlos, all diese Überprüfungen durchzuführen, wenn die requestPermissions nicht funktionieren? In meinem Code überprüfe ich nur, ob ich die Erlaubnis habe und wenn nicht, rufe ich die requestPermissions auf. und später werde ich das wohl ändern. und ich habe die requestPermissions-Syntax genau so gemacht, wie Sie es gesagt haben, aber sie funktioniert bei mir nicht.
Idan Ayzen
Da Sie Ihren tatsächlichen requestPermissions () - Code nicht veröffentlicht haben, habe ich ein vollständiges Arbeitsbeispiel veröffentlicht. Funktioniert gut für mich.
NightSkyDev
Ich habe gerade meinen aktuellen requestPermissions () - Code gepostet. Vielen Dank für Ihre Hilfe :)
Idan Ayzen
1
@Phil - Beides zum Beispiel hinzugefügt. Wie Sie sehen, ist es genauso einfach, requestPermission direkt aufzurufen, und Sie müssen dies tun, wenn Sie mehrere Berechtigungen anfordern, da diese Methode nur ein Wrapper ist, um eine Berechtigung aufzurufen.
NightSkyDev
5
Vielen Dank für die Hervorhebung von "Definieren Sie zuerst die Berechtigung (wie Sie es in Ihrem Beitrag getan haben) im Manifest, andernfalls wird Ihre Anfrage automatisch abgelehnt". Meins war wie folgt: <Verwendungsberechtigung android: name = "android.permission.GET_ACCOUNTS" android: maxSdkVersion = "22" tools: replace = "maxSdkVersion" /> Ich habe die "22" in "23" geändert
Jimmy Ilenloa
47

Ich hatte das gleiche Problem und es stellte sich heraus, dass das Manifest Merger Tool ein android:maxSdkVersionAttribut aus einer Abhängigkeit gezogen hat.

Um die tatsächlichen Berechtigungen anzuzeigen, die Sie in Ihrer APK anfordern, können Sie das aaptTool folgendermaßen verwenden:

/path/to/android-sdk/build-tools/version/aapt d permissions /path/to/your-apk.apk

in meinem Fall druckte es:

uses-permission: name='android.permission.WRITE_EXTERNAL_STORAGE' maxSdkVersion='18'

obwohl ich maxSdkVersionin meinem Manifest kein angegeben hatte . Ich habe dieses Problem behoben, indem <uses-permission>ich in meinem Manifest Folgendes geändert habe:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>

(wo sich der Tools-Namespace befindet http://schemas.android.com/tools)

hrunk
quelle
4
Du rettest meinen Tag! Danke
Khang .NT
1
@usman es ist nicht notwendig, dass es für alle funktionieren sollte, möglicherweise ist Ihr Fall anders. Bitte posten Sie Ihre Frage, jemand
löst
2
Um das tatsächliche Berechtigungsmanifest (zusammengeführt) anzuzeigen, können Sie es ab sofort ohne andere Tools wie anzeigen aapt. Während Sie Ihre AndroidManifest.xml in Android Studio sehen, sehen Sie sich die untere Registerkarte an und klicken Sie einfach auf die Merged ManifestRegisterkarte.
Adadion
Du bist ein Zauberer. Du bist ein Zauberer !!
Blastervla
26

Ich musste um Erlaubnis bitten, bekam WRITE_EXTERNAL_STORAGEaber kein Popup, obwohl ich all die verschiedenen Vorschläge ausprobiert hatte.

Der Schuldige am Ende war HockeyApp. Es verwendet das Zusammenführen von Manifesten, um seine eigene Berechtigung WRITE_EXTERNAL_STORAGEeinzuschließen, es sei denn, es wendet eine maximale SDK-Version darauf an.

Der Weg, um dieses Problem zu umgehen, besteht darin, es in Ihre Manifest-Datei aufzunehmen, aber durch ein Ersetzen zu ersetzen, um die Version und den Erfolg der HockeyApp zu überschreiben!

4.7.2 Andere Abhängigkeiten, die die Berechtigung für externen Speicher anfordern (SDK-Version 5.0.0 und höher) Um für Android O bereit zu sein, beschränken HockeySDK-Android 5.0.0 und höher die WRITE_EXTERNAL_STORAGE Berechtigung mit dem Filter maxSdkVersion. In einigen Anwendungsfällen, z. B. wenn eine App eine Abhängigkeit enthält, für die diese Berechtigung erforderlich ist, macht es maxSdkVersion diesen Abhängigkeiten unmöglich, die Berechtigung zu erteilen oder anzufordern. Die Lösung für diese Fälle lautet wie folgt:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>

Dies führt dazu, dass andere Attribute aus Manifesten mit niedriger Priorität ersetzt werden, anstatt zusammengeführt zu werden.

https://support.hockeyapp.net/kb/client-integration-android/hockeyapp-for-android-sdk#permissions-advanced

Talha
quelle
Danke, es war den ganzen Tag mein Problem.
Miguel Orellana
12

Ersetzen:

ActivityCompat.requestPermissions(this, new String[]{"Manifest.permission.READ_PHONE_STATE"}, 225);

mit:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 225);

Die tatsächliche Zeichenfolge für diese Berechtigung lautet nicht "Manifest.permission.READ_PHONE_STATE". Verwenden Sie das Symbol Manifest.permission.READ_PHONE_STATE.

CommonsWare
quelle
1
nicht für mich arbeiten. meine App an die Arbeit 16-23 sdk Version konfiguriert
Ciro
Sie sollten android.Manifest.permission.READ_PHONE_STATE
Rana
4

Ich habe meine SDK-Zielversion von 22 auf 23 aktualisiert und es hat perfekt funktioniert.

Shyam Sunder
quelle
1
Ja, aber das war kein Zufall. Der Grund dafür ist, dass 23 mit der Interpretation von Android <uses-permission>als zukünftige Codeaktion anstelle einer Anforderung bei der Installation begann.
Eliot Gillum
4

Es könnte kein Problem mit einer einzelnen Zeile Ihres Codes sein.

Auf einigen Geräten (ich erinnere mich nicht, ob es auf Android verfügbar ist) enthält das Dialogfeld "Berechtigung" ein Kontrollkästchen mit der Bezeichnung "Nie wieder fragen". Wenn Sie mit aktiviertem Kontrollkästchen auf Verweigern klicken, werden Sie nicht erneut zur Eingabe dieser Berechtigung aufgefordert. Sie wird der App automatisch verweigert. Um dies zu bestätigen, müssen Sie zu Einstellungen -> App -> Berechtigungen gehen und diese Dauerwelle für die App erneut aktivieren. Schalten Sie es dann aus, um es erneut abzulehnen. Möglicherweise müssen Sie die App öffnen, bevor Sie sie wieder ausschalten können. Sie sind sich nicht sicher.

Ich weiß nicht, ob Ihr Nexus es hat. Vielleicht einen Versuch wert.

androidguy
quelle
Ich hatte diese Situation. Der beste Ausweg ich denken konnte, war zu überprüfen , PackageManager.PERMISSION_DENIEDin onRequestPermissionsResult()und stellen Sie die Benutzeroberfläche den Benutzer zu erklären , dass die Berechtigungen manuell eingestellt werden mußten und offen Settings.ACTION_APPLICATION_DETAILS_SETTINGS.
Roy Solberg
1

Für mich bestand das Problem darin, fälschlicherweise eine Gruppe anstelle der tatsächlichen Berechtigungen anzufordern.

Gemeiner Mann
quelle
1

Ich hatte das gleiche Problem und löste es, indem ich Manifest.permission.READ_PHONE_STATE durch android.Manifest.permission.READ_PHONE_STATE ersetzte.

Beaux
quelle
1

Das ist mir gerade passiert. Es stellte sich heraus, dass ich ALLE Berechtigungen angefordert hatte, als ich nur nach GEFÄHRLICHEN Berechtigungen filtern musste, und es fing plötzlich an zu funktionieren.

fun requestPermissions() {
    val missingDangerPermissions = PERMISSIONS
            .filter { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }
            .filter { this.getPackageManager().getPermissionInfo(it, PackageManager.GET_META_DATA).protectionLevel == PermissionInfo.PROTECTION_DANGEROUS } // THIS FILTER HERE!

    if (missingDangerPermissions.isNotEmpty()) {
        Log.i(TAG, "Requesting dangerous permission to $missingDangerPermissions.")
        ActivityCompat.requestPermissions(this,
                missingDangerPermissions.toTypedArray(),
                REQUEST_CODE_REQUIRED_PERMISSIONS);
        return
    } else {
        Log.i(TAG, "We had all the permissions we needed (yay!)")
    }
}
Benjamin H.
quelle
Woher bekommen Sie die Variable von ContextCompat? Ich habe versucht, aber Variable nicht gefunden Ergebnis?
Gumuruh
1

Ich bin auf dieses Problem bei Samsung S8 und N8 gestoßen (in keinem anderen gefunden)

Das Problem liegt also in der Verwendungsberechtigung der Manifestdatei

<uses-permission android:name="android.permission.CAMERA"
android:requiredFeature="true" />

Aus irgendeinem Grund ist das Attribut android:requiredFeatureder Schuldige. und ich habe keine Erklärung dafür gefunden, warum.

zum lösen einfach entfernen,

<uses-permission android:name="android.permission.CAMERA" />
Grandia
quelle
0

Ich hatte das gleiche Problem. Ich habe auf buildToolsVersion "23.0.3" aktualisiert. Es hat plötzlich funktioniert. Hoffe, das hilft jedem, der dieses Problem hat.

Bk245
quelle
0

Für mich war das Problem, dass ich einen ungültigen Anforderungscode hatte. Ich wähle 0xDEADBEEF als Anforderungscode und es ist stillschweigend fehlgeschlagen (vielleicht wird es intern in etwas kleiner als 32-Bit umgewandelt?). Wenn ich 255 wähle, hat alles gut funktioniert, wie oben beschrieben, NightSkyDev.

griffin2000
quelle
Die Dokumente geben an requestCode, dass ≥ 0 sein sollte. 0xDEADBEEF ist <0.
Fls'Zen
0

Die oben genannten Informationen sind gut, aber Einstellung targetSdkVersionauf 23 (oder höher) ist entscheidend für Android , die zu interpretieren <uses-permission>Tag im Manifest als „ich in Code frage“ statt „ich bei der Installation verlangen.“ Viele Quellen werden Ihnen sagen, dass Sie das <uses-permission>Tag benötigen , aber niemand sagt, warum und wenn Sie diesen Wert nicht festgelegt haben, werden Sie stundenlang so verwirrt sein wie ich.

Eliot Gillum
quelle
0

Für mich war der Fehler im Manifest: Die Erlaubnis war in Großbuchstaben. Android Studio schlägt mir die Berechtigungen in Großbuchstaben vor. Das interessiert mich nicht und ich habe zwei Stunden gebraucht, um dieses Problem zu beheben.

Die richtige Syntax für die Berechtigung lautet
<Verwendungsberechtigung android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />

AlainPre
quelle
0

Es ist mir passiert, dass ich es auf API 23 ausgeführt habe und den Code verwenden musste, um eine Berechtigung anzufordern, wie dieser Code unten, um es auf die Erstellungsmethode zu setzen. Beachten Sie, dass MY_PERMISSIONS_REQUEST_READ_LOCATION eine Ganzzahl ist, die 1 Beispiel entspricht. int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1:

if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.M) {requestPermissions (neuer String [] {Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_READ_LOCATION); }}

Jair Martinez
quelle
0

Vielleicht könnte diese Lösung eher jemandem helfen als:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

verwenden :

ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

also fügen wir android.zuManifest.permission.WRITE_EXTERNAL_STORAGE

user10955646
quelle
0

Für mich bestand das Problem darin, dass meine Hauptaktivität direkt nach der Anfrage eine weitere Aktivität startete. Das hat den Dialog abgelöst und wurde nie gesehen.

JohnT
quelle
0

Vergessen Sie nicht, die Berechtigungen ohne zusätzliche Leerzeichen im Manifest zu schreiben. In meinem Fall hatte ich:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />

Aber schauen Sie, am Ende gibt es einen zusätzlichen Platz. Schreiben Sie es einfach richtig

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Und es funktioniert jetzt

Luis Cabrera Benito
quelle
0

Unabhängig davon, was Sie tun, überprüfen Sie in der Manifest-Datei, ob Sie die erforderliche Berechtigung deklarieren.


    <!--Declaring the required permissions-->
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.CAMERA" />


Fahren Sie dann mit den nächsten Schritten fort.

Jin Lim
quelle
0

Hier ist eine weitere Erfahrung, die ich mit euch teilen möchte. Das Problem trat auf, nachdem ich den folgenden Code implementiert hatte, um nach BLE-Zugriffsberechtigungen zu suchen:

final String requiredPermission = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) ?
            android.Manifest.permission.ACCESS_FINE_LOCATION :
            android.Manifest.permission.ACCESS_COARSE_LOCATION;

Ich wollte zwischen FINE- und COARSE-Standortberechtigungsanforderungen unterscheiden, die beide im Manifest definiert wurden. Bei der Suche nach der Berechtigung ACCESS_COARSE_LOCATION wurde das Dialogfeld "Berechtigung anfordern" nie angezeigt, sondern onRequestPermissionsResultimmer mit PERMISSION_DENIED aufgerufen (falls die Berechtigung in den App-Einstellungen nicht aktiviert war). Also habe ich die Prüfung für BUILD.SDK entfernt und nur nach ACCESS_FINE_LOCATIONund voilla gesucht, der fehlende Dialog wurde angezeigt.

final String requiredPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;

hat den Trick gemacht.

Die Manifest-Quelle enthält:

<uses-permission android:name="android.permission.COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

aber die apk enthielt android.permission.ACCESS_FINE_LOCATIONnur. Irgendwann während des Baus war das COARSE_LOCATIONentfernt worden.

Ich hoffe, dies könnte jemandem helfen, der das gleiche Problem hat.

Peter
quelle