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>

Ü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);
}

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)


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


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.


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.


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.


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.


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.


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!)")
    }
}

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" />

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.


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.


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.


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" />


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); }}


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


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.


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


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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.