3

ich eine App mit targetSdkVersion haben = 23, compileSdkVersion = 23 mit der Haupttätigkeit Setup wie folgtfalsche Result in Aktivität des onRequestPermissionsResult wenn Anfrage Erlaubnis von Fragment

- HomeActivity (AppCompatActivity) 
    - FragmentA (V4 Fragment) 
    - ViewPager 
     - NestedFragmentA (V4 Fragment) 
     - NestedFragmentB (v4 Fragment) 
     - NestedFragmentC (v4 Fragment) 
     - NestedFragmentD (v4 Fragment) 
    - Fragment B (V4 Fragment) 
    - Fragment C (V4 Fragment) 

Und in HomeActivity

public static final String PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    Log.i("Logger", "Request Code: " + String.valueOf(requestCode)); 

    // Handle permission request result 
} 

I Lesen Sie diese Antwort von @CommonsWare,

https://stackoverflow.com/a/33170531/760363

dass das onRequestPermissionsResult im verschachtelten Fragment nie aufgerufen wird (in meinem Fall wird das Ergebnis zu HomeActivity zurückkehren), aber mir geht es gut, ich werde Fragment des Ergebnisses manuell benachrichtigen.

Aber das Problem ist, wenn ich in HomeActivity um Erlaubnis ersuche, alles funktioniert gut.

HomeActivity

// Request permission from HomeActivity 
// Supply 101 as request code, get 101 back 

@Override 
public void clickSomething(View v) { 
    requestPermissions(new String[]{PERMISSION}, 101); 
} 

// Logcat 
Logger: Request Code: 101 <<< CORRECT 

Aber in FragmetnA oder NestedFragmentA, wenn ich von verschachtelten Fragment anfordern, die requestCode, die HomeActivity Rückkehr

fragmenta

// Request permission from FragmentA 
// Supply 102 as request code, get 358 back 

@Override 
public void clickAnotherThing(View v) { 
    requestPermissions(new String[]{HomeActivity.PERMISSION}, 102); 
} 

// Logcat 
Logger: Request Code: 358 <<< INCORRECT 
geändert hat

NestedFragmentA

// Request permission from NestedFragmentA 
// Supply 103 as request code, get 615 back 

@Override 
public void clickDifferentThing(View v) { 
    requestPermissions(new String[]{HomeActivity.PERMISSION}, 103); 
} 

// Logcat 
Logger: Request Code: 615 <<< INCORRECT 

Haben Sie eine Ahnung, was dieses Problem verursachen würde?

+0

Sie können Requestpermission von verschachtelten Frgament nicht aufrufen ... bitte besuchen Sie diese http://StackOverflow.com/questions/33169455/onrequestpermissionsresult-not-being-in-dialog-fragment –

Antwort

7

Ich würde nicht die Tatsache negieren, dass "Nested Fragments do not receive request permissions (onRequestPermissionsResult()) callback".

Aber was ich hier tun werde, ist das von Ihnen beobachtete Verhalten bezüglich der verschiedenen "seltsamen" Anfragecodes, die in der Containeraktivität für die requestPermissions() empfangen wurden, die von den Fragmenten und den verschachtelten Fragmenten gemacht wurde.

dies Ihr Beispiel betrachten die erklären lassen -

- HomeActivity (AppCompatActivity) 
    - FragmentA (V4 Fragment) 
    - ViewPager 
     - NestedFragmentA (V4 Fragment) 
     - NestedFragmentB (v4 Fragment) 
     - NestedFragmentC (v4 Fragment) 
     - NestedFragmentD (v4 Fragment) 
    - Fragment B (V4 Fragment) 
    - Fragment C (V4 Fragment) 

onRequestPermissionsResult() nur zum besseren Verständnis in HomeActivity, FragmentA and NestedFragmentA Implementieren mit Protokollen der Anforderungscode Druck erhalten

@Override 
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
      Log.d("debug", "req code :: " + requestCode);  
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 

Auch bestimmte Erlaubnis von FragmentA und NestedFragmentA fordern. Nehmen wir exmaple Standort Berechtigungen

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

Nun, wenn wir requestPermissions() aus Fragmenten oder verschachtelte Fragmente, ruft Fragment class's requestPermissions() die wiederum ruft FragmentHostCallback's onRequestPermissionsFromFragment() die wiederum FragmentActivity's requestPermissionsFromFragment() nennt. Jetzt liegt hier die Transformation Ihres Anfragecodes. nach dem Anforderungscode Validierung, ruft er

ActivityCompat's requestPermissions() 

ABER

mit dem Anforderungscode umgewandelt -

ActivityCompat.requestPermissions(this, permissions,((fragment.mIndex + 1) << 8) + (requestCode & 0xff)); 

So die geänderte Anforderungscode ist -

((fragment.mIndex + 1) << 8) + (requestCode & 0xff) 

wo fragment.mIndex ist die Fragmentstufe. Also für sofortige Fragment (bedeutet direkt ein Kind der Container-Aktivität), wird es "0" und für sofortige verschachtelte Fragment (bedeutet das Fragment unmittelbar in einem Fragment) wird es "1" und es wird basierend auf wie erhöht werden tief ist dein Fragment verschachtelt.

In unserem Fall für FragmentA ändert Anforderungscode zu

(((0 + 1) << 8) + (102 & 0xff)) which computes to 358 

Und für NestedFragmentA, Änderungen Anforderungscode zu

(((1 + 1) << 8) + (102 & 0xff)) which computes to 614 

Jetzt wissen wir, wo die Anforderungs-Code-Änderungen. Lass uns von ActivityCompat.requestPermissions() fortfahren. Wir kennen also ActivityCompat.requestPermissions(), da wir diese Methode verwenden, um Berechtigungen von Aktivitäten anzufordern. Außerdem wissen wir, dass dies einige Operationen ausführen wird und dem Benutzer das Berechtigungs-Popup angezeigt wird, um die angeforderte Berechtigung zu akzeptieren/abzulehnen.

Jetzt kommen wir zu onRequestPermissionsResult(). Wenn der Benutzer akzeptiert/ablehnt, wird onRequestPermissionsResult() der Containeraktivität aufgerufen, weil schließlich ActivityCompat.requestPermissions() aufgerufen wurde. Angenommen, Sie akzeptieren/verweigern die Erlaubnis von FragmentA Daher werden Sie die Log-

req code ::358 

Danach wird aufrufen FragmentActivity's onRequestPermissionsResult()

super.onRequestPermissionsResult(requestCode, permissions, grantResults); 

erhalten, die eine gewisse Validierung wiederum führt und rufen

frag.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults); 

Bow Sie können sehen, die Anfrage Code in frag.onRequestPermissionsResult() ist anders übergeben. requestCode war 358 und nach &0xff wird es wieder 102. Voila !! Das bedeutet, obwohl wir unterschiedlichen Anforderungscode (358) in HomeActivity's onRequestPermissionsResult(), doch wir fordern FragmentA's onRequestPermissionsResult() mit dem ursprünglichen Anforderungscode (102) So erhalten wir diese Protokolle von FragmentA bekamen - zu NestedFragmentA kommenden

req code ::358 

Jetzt.Angenommen, Sie akzeptieren/verweigern die Erlaubnis von NestedFragmentA So werden Sie das Protokoll erhalten in HomeActivity -

req code ::614 

Aber wir wissen onRequestPermissionsResult() nicht für verschachtelte Fragmente aufgerufen werden, so werden wir keine Protokolle erhalten in NestedFragmentA's onRequestPermissionsResult()

Ich denke, ich habe den Grund erklärt, warum wir verschiedene Anfragecodes in der Container-Aktivität für die requestPermissions() von dem Fragment und verschachtelten Fragmenten erhalten.

Also würde ich sagen, dass für die Fragmente, die nicht verschachtelt sind requestPermissions() nur aus den Fragmenten und implementieren onRequestPermissionsResult() nur dort und nicht in der Container-Aktivität. Bei verschachtelten Fragmenten sollte man requestPermissions() für die Berechtigungen angeben, die von den verschachtelten Fragmenten nur vom übergeordneten Fragment benötigt werden. Es scheint, dies ist die einzige Problemumgehung.

+1

Wow, ich wünschte, ich könnte Sie upvote tausendmal!! –

+0

Weitere Fragen, 1.) Kann ich sagen, wenn ich onRequestPermissionsResult nicht überschreibe oder wenn ich super in Container-Aktivität rufe, wird das FragmentA den richtigen Code erhalten? 2.) Ist dieses Verhalten sowohl für ActivityCompat als auch für Activity identisch? –

+1

1. Ja 2. ActivityCompat.requestPermissions() ruft wiederum activity.requestPermissions() auf –

Verwandte Themen