onRequestPermissionsResult wird nicht im Fragment aufgerufen, wenn es sowohl im Fragment als auch in der Aktivität definiert ist


166

Ich habe ein Fragment, in dem ich Recyclerview habe und Daten in diesem Recyclerview mithilfe des Recyclerview-Adapters einstelle.

Jetzt habe ich eine Schaltfläche im Listenelement des Adapters, auf die ich klicken muss, um die READ_EXTERNAL_STORAGE-Berechtigung in Android auf ein neues Berechtigungsmodell in Android zu überprüfen.

Ich habe eine neue Funktion im Fragment dieses Adapters erstellt, um zu überprüfen, ob eine Berechtigung erteilt wurde oder nicht, und um eine Berechtigung anzufordern, falls diese noch nicht erteilt wurde.

Ich habe MyFragment.this als Parameter im Adapter übergeben und die Methode des Fragments aufgerufen, indem ich auf die Schaltfläche im Adapter klicke.

Ich habe den folgenden Code verwendet, um requestPermission in Fragment aufzurufen.

if(ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED){
       requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                ConstantVariables.READ_EXTERNAL_STORAGE);
    }

Ich habe die onRequestPermissionsResultMethode in Fragment mit dem folgenden Code überschrieben :

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case ConstantVariables.READ_EXTERNAL_STORAGE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, proceed to the normal flow.
                startImageUploading();
            } else {}

Es wird jedoch nicht aufgerufen, stattdessen wird die onRequestPermissionsResult-Methode dieser Aktivität aufgerufen.

Ich habe dieselbe onRequestPermissionsResult-Methode auch in der übergeordneten Aktivität des Fragments definiert und sie wird aufgerufen.

Ich kann die onRequestPermissionsResult-Methode der Aktivität nicht entfernen, möchte jedoch die onRequestPermissionsResult-Methode des Fragments aufrufen, wenn ich eine Berechtigung vom Fragment anfordere. Wie kann ich das machen? Mache ich hier etwas falsch, bitte helfen Sie mir, wenn jemand hier eine Idee hat.


1
Verweisen Sie auf diesen Link Laufzeitberechtigungen in Fragment Dies ist die genaue Lösung
Antony Jackson

Antworten:


371

Überarbeitete Antwort, um umfassendere Themen abzudecken

Ich denke, Sie verwechseln die Methode für Fragment und Aktivität. Hatte letzten Monat ein ähnliches Problem mit meinem Projekt. Bitte überprüfen Sie, ob Sie endlich Folgendes haben:

  1. Verwenden Sie in AppCompatActivity die Methode ActivityCompat.requestpermissions
  2. In v4 Support Fragment sollten Sie Requestpermissions verwenden
  3. Catch ist, wenn Sie AppcompatActivity.requestpermissions in Ihrem Fragment aufrufen, wird der Rückruf zur Aktivität und nicht zum Fragment
  4. Stellen Sie sicher, dass Sie super.onRequestPermissionsResultvon der Aktivität aus anrufen onRequestPermissionsResult.

Sehen Sie, ob es hilft.


9
Nur um zu überprüfen, stellen Sie sicher, dass Sie super.onrequestpermissionresult in Ihrer Aktivität eingestellt haben
VarunJoshi129

27
Wenn Sie super.onrequestpermissionresultdas Ergebnis onrequestpermission der Aktivität hinzufügen, rufen Sie das Ergebnis onrequestpermission des Fragments auf, wenn ich die Berechtigung mit anfordere requestpermissions. Dies funktioniert jetzt gut, vielen Dank .. :)
Prithniraj Nicyone

1
Das super.onrequestpermission-Ergebnis fehlte im Aktivitätsrückruf, was dazu führte, dass mein Fragmentrückruf nicht aufgerufen wurde
sakis kaliakoudas

4
requestPermissions () erfordert API-Level 23. Gibt es eine andere Lösung, die für API-Level 21 abwärtskompatibel ist?
Adam Hurwitz

2
@ msc87 1. In onRequestPermissionsResult von Aktivität und Fragment sollte die erste Zeile lauten: super.onRequestPermissionsResult (requestCode, permissions, grantResults); 2. In einem Fragment, in dem Sie die nicht erteilte Berechtigung erkennen, rufen Sie einfach die requestPermission-Methode wie folgt auf
AREF

122

Ich habe die Standortgenehmigung von einem Fragment angefordert und im Fragment musste ich Folgendes ändern:

            ActivityCompat.requestPermissions(getActivity(), new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

dazu:

            requestPermissions(new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

dann wurde das onRequestPermissionsResult im Fragment aufgerufen.


2
Funktioniert wie ein Zauber :)
Antonio Vlasic

1
Es funktioniert nicht mit Kotlin. Kannst du mir bitte helfen? Hier wird diese Anfrage
Arbaz.in

Danke :), du
sparst

19

Dies ist ein häufiger Fehler, den Menschen beim Codieren für Marshmallow machen.

In AppCompatActivity sollten Sie ActivityCompat.requestPermissions verwenden. In android.support.v4.app.Fragment sollten Sie einfach requestPermissions verwenden (dies ist eine Instanzmethode von android.support.v4.app.Fragment). Wenn Sie ActivityCompat.requestPermissions in einem Fragment aufrufen, wird der Rückruf onRequestPermissionsResult aufgerufen die Aktivität und nicht das Fragment.

requestPermissions(permissions, PERMISSIONS_CODE);

Wenn Sie diesen Code aus einem Fragment aufrufen, verfügt er über eine eigene requestPermissions-Methode.

Das Grundkonzept lautet also: Wenn Sie sich in einer Aktivität befinden, rufen Sie an

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

und wenn in einem Fragment, rufen Sie einfach an

requestPermissions(new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

Als Referenz habe ich die Antwort von diesem Link erhalten: https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

Die Methode requestPermissionsfür Fragmente erfordert API-Level 23 oder höher.
Wenn Ihre App auf eine niedrigere Version abzielt, können Sie diese verwenden

FragmentCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            ConstantVariables.READ_EXTERNAL_STORAGE);

Zuerst müssen Sie die support-v13-Abhängigkeit hinzufügen:

implementation "com.android.support:support-v13:$supportLibVersion"

FragmentCompat ist veraltet von Version 27.1.0
Raj kannan Iyyappan

6

ändere das :

ActivityCompat.requestPermissions(
    activity,
    arrayOf(Manifest.permission.READ_CONTACTS),
    PERMISSIONS_REQUEST_READ_CONTACTS
)

dazu:

requestPermissions(
     arrayOf(Manifest.permission.READ_CONTACTS),
     PERMISSIONS_REQUEST_READ_CONTACTS
)

Die untere Version wird in einem Fragment verwendet (onRequestPermissionsResult wird in Fragment aufgerufen). Die ActivityCompat-Version wird verwendet, wenn sich das onRequestPermissionsResult in der Aktivität befindet.
Roar Grønmo

1
private void showContacts() {
 if (getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
         != PackageManager.PERMISSION_GRANTED) {
     requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
             PERMISSIONS_REQUEST_READ_STORAGE);
 } else {
     doShowContacts();
 }
}

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions,
     int[] grantResults) {
 if (requestCode == PERMISSIONS_REQUEST_READ_STORAGE
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     doShowContacts();
 }
 }

Berechtigung ändern


2
Hallo Benutzer2002721; Ihr Code mag korrekt sein, aber mit einem gewissen Kontext würde er eine bessere Antwort geben. Sie könnten beispielsweise erklären, wie und warum diese vorgeschlagene Änderung das Problem des Fragestellers lösen würde, möglicherweise einschließlich eines Links zu der entsprechenden Dokumentation. Dies würde es für sie nützlicher machen und auch für andere Site-Leser, die nach Lösungen für ähnliche Probleme suchen.
Vince Bowdren

Das Programm kann ein Array außerhalb der Grenzen auslösen, wenn Sie versuchen, auf den Index 0 von grantResults zuzugreifen, ohne zuerst die Länge zu überprüfen. Es ist meinem Programm passiert. Ich habe die if-Anweisung für grantResults als innere if-Anweisung getrennt, um dies zu verhindern, und sie funktioniert jetzt einwandfrei.
Peter Griffin

1

Diese akzeptierte Antwort funktioniert bei mir nicht, daher habe ich meine eigene Lösung gefunden, die unten erläutert wird:

1. Zuerst habe ich eine Methode in Fragment erstellt:

public static void MyOnRequestPermissionResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if (requestCode == 1 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission: true");
        } else {
            Log.d(TAG, "permission: false");
        }
}

2.Und nannte es dann von seiner zugrunde liegenden Aktivität:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode ==1){
        SignupFragment.MyOnRequestPermissionResult(requestCode, permissions, grantResults);
    }
}

Und es funktioniert ...


0

Stellen Sie sicher, dass beide PERMISSION_REQUEST_CODE in onRequestPermissionsResultals auch in Ihrem Fragmentden gleichen Wert enthält.


0

Für das tragetSDK 28 würden die SDK-Prüfung (> 23) und die Anforderungsberechtigungen vom Fragment funktionieren. ActivityCompat.requestPermissions schlägt fehl (wenn Sie den Anforderungscode unter 65536 festlegen, wird das Berechtigungsdialogfeld angezeigt, und wenn der Benutzer die Berechtigung zulässt, werden die Berechtigungen bereitgestellt, es erfolgt jedoch kein Rückruf. Wenn Sie jedoch über 65536 festlegen, wird ActivityCompat.requestPermissions ausgeführt scheitern sofort. Ich kenne die Gründe für diese Logik nicht. Kann ein Fehler oder eine Absicht sein.

Arbeitscode:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }

Sie müssen die Versionsprüfung nicht durchführen. In Versionen unter 23 wird nur der Wert "Berechtigung erteilt" zurückgegeben. Wahl des Entwicklers hier: Vermeiden Sie der Einfachheit halber den '
if'


0

Ich hatte das gleiche Problem. Ihr Fragment kann über das Aktivitätslayout initialisiert werden. So wie das:

main_activty.xml

<fragment
    android:id="@+id/fragment"
    android:name="com.exampe.SomeFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Dieses Problem wurde für mich gelöst, als ich es FragmentTransactionstattdessen verwendete


0

In APIs unter 23 können Sie eine Schnittstelle in der Aktivität erstellen und diese dann im untergeordneten Fragment implementieren. Wenn Sie eine Berechtigungsanforderung erhalten, wird die Aktivität an die implementierte Schnittstelle im Fragment übergeben. So einfach ist das :)


0

Sie können die folgende Fragment-Methode aufrufen

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
                doActionBecauseNowYouCanBro();
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
                showWhyRequestPermissionsAndDontBlockUserItsCalledManners();
            }
            return;
    }
    // Other 'case' lines to check for other
    // permissions this app might request.

}

-5

Dieses Problem wurde tatsächlich von NestedFragments verursacht. Grundsätzlich haben die meisten Fragmente ein HostedFragment erweitert, das wiederum ein CompatFragment erweitert. Diese verschachtelten Fragmente verursachten Probleme, die schließlich von einem anderen Entwickler des Projekts gelöst wurden.

Er hat ein paar Sachen auf niedriger Ebene gemacht, wie zum Beispiel Bit-Switching, damit das funktioniert, also bin ich mir der tatsächlichen endgültigen Lösung nicht sicher


3
Anstatt eine Antwort zu kopieren, können Sie auch einen Link angeben
stackoverflow.com/a/33081173/630833
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.