onRequestPermissionsResult n'est pas appelé dans le fragment s'il est défini à la fois dans le fragment et dans l'activité

167

J'ai un fragment dans lequel j'ai recyclerview et les données de réglage dans ce recyclerview à l'aide de l'adaptateur recyclerview.

Maintenant, j'ai un bouton dans l'élément de liste de l'adaptateur en cliquant sur lequel je dois vérifier l'autorisation READ_EXTERNAL_STORAGE dans Android pour un nouveau modèle d'autorisation dans Android.

J'ai créé une nouvelle fonction dans le fragment de cet adaptateur pour vérifier si l'autorisation est accordée ou non et demander l'autorisation si elle n'est pas déjà accordée.

J'ai passé MyFragment.this en tant que paramètre dans l'adaptateur et en appelant la méthode du fragment sur le bouton cliquez dans l'adaptateur.

J'ai utilisé le code ci-dessous pour appeler requestPermission en fragment.

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

J'ai remplacé la onRequestPermissionsResultméthode dans fragment en utilisant le code ci-dessous:

@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 {}

Mais il n'est pas appelé, au lieu de l'appel de la méthode onRequestPermissionsResult de cette activité.

J'ai également défini la même méthode onRequestPermissionsResult dans l'activité parent du fragment et elle est appelée.

Je ne peux pas supprimer la méthode onRequestPermissionsResult de l'activité mais je souhaite appeler la méthode onRequestPermissionsResult du fragment lorsque je demande l'autorisation du fragment. Comment puis-je faire ceci? Suis-je en train de faire quelque chose de mal ici, aidez-moi s'il vous plaît si quelqu'un a une idée ici.

Prithniraj Nicyone
la source
1
renvoyer ce lien les autorisations d'exécution dans le fragment C'est la solution exacte
Antony jackson

Réponses:

373

Réponse modifiée pour couvrir des problèmes plus larges

Je pense que vous confondez la méthode du fragment et de l'activité. J'ai eu un problème similaire à mon projet le mois dernier. Veuillez vérifier si vous avez enfin les éléments suivants:

  1. Dans AppCompatActivity, utilisez la méthode ActivityCompat.requestpermissions
  2. Dans le fragment de support v4, vous devez utiliser requestpermissions
  3. Catch est que si vous appelez AppcompatActivity.requestpermissions dans votre fragment, le rappel viendra en activité et non en fragment
  4. Assurez-vous d'appeler super.onRequestPermissionsResultdepuis l'activité onRequestPermissionsResult.

Voyez si cela aide.

VarunJoshi129
la source
9
Juste pour vérifier que vous avez défini le résultat super.onrequestpermission dans votre activité
VarunJoshi129
27
L'ajout super.onrequestpermissionresultde onrequestpermissionresult de l'activité appelle le onrequestpermissionresult du fragment lorsque je demande l'autorisation d'utiliser requestpermissions. Cela fonctionne bien maintenant, merci beaucoup .. :)
Prithniraj Nicyone
1
Le résultat de super.onrequestpermission était absent du rappel d'activité, ce qui a conduit à ce que mon rappel de fragment ne soit pas appelé
sakis kaliakoudas
4
requestPermissions () nécessite le niveau d'API 23. Existe-t-il une autre solution rétrocompatible pour le niveau d'API 21?
Adam Hurwitz
2
@ msc87 1. dans onRequestPermissionsResult de l'activité et du fragment, la première ligne doit être: super.onRequestPermissionsResult (requestCode, permissions, grantResults); 2. dans un fragment où vous reconnaissez l'autorisation non accordée, appelez simplement la méthode requestPermission comme ceci: requestPermissions (new String [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF
122

J'ai demandé l'autorisation de localisation à un fragment et dans le fragment, je devais changer ceci:

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

pour ça:

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

puis onRequestPermissionsResult a été appelé dans le fragment.

Badr
la source
2
Fonctionne comme un charme :)
Antonio Vlasic
1
il ne fonctionne pas avec Kotlin pouvez - vous me aide pour la même chose ici est utilisé ce requestPermissions (contexte que l' activité, permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in
Merci :), vous gagnez mon temps
Axrorxo'ja Yodgorov
19

C'est une erreur courante que font les gens lors du codage de la guimauve.

Dans AppCompatActivity, vous devez utiliser ActivityCompat.requestPermissions; Lorsque vous êtes dans android.support.v4.app.Fragment, vous devez simplement utiliser requestPermissions (il s'agit d'une méthode d'instance de android.support.v4.app.Fragment) Si vous appelez ActivityCompat.requestPermissions dans un fragment, le rappel onRequestPermissionsResult est appelé sur l'activité et non le fragment.

requestPermissions(permissions, PERMISSIONS_CODE);

Si vous appelez ce code à partir d'un fragment, il possède sa propre méthode requestPermissions.

Donc, le concept de base est, si vous êtes dans une activité, alors appelez

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

et si dans un fragment, il suffit d'appeler

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

Pour la référence, j'ai obtenu la réponse à partir de ce lien https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/

Farruh Habibullaev
la source
6

La méthode requestPermissionssur les fragments nécessite le niveau d'API 23 ou supérieur.
Si votre application cible une version inférieure, vous pouvez utiliser

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

Vous devez d'abord ajouter la dépendance support-v13:

implementation "com.android.support:support-v13:$supportLibVersion"
Juan Cruz Soler
la source
FragmentCompat est obsolète à partir de la version 27.1.0
Raj kannan Iyyappan
6

change ça :

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

pour ça :

requestPermissions(
     arrayOf(Manifest.permission.READ_CONTACTS),
     PERMISSIONS_REQUEST_READ_CONTACTS
)
delayKg
la source
La version inférieure est à utiliser dans un fragment (onRequestPermissionsResult est appelé dans fragment), la version ActivityCompat est à utiliser lorsque onRequestPermissionsResult est situé dans Activity.
Roar Grønmo le
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();
 }
 }

modifier l'autorisation

user2002721
la source
2
Salut user2002721; votre code pourrait être correct, mais avec un certain contexte, il ferait une meilleure réponse; par exemple, vous pourriez expliquer comment et pourquoi ce changement proposé résoudrait le problème de l'interrogateur, en incluant peut-être un lien vers la documentation pertinente. Cela le rendrait plus utile pour eux, et aussi plus utile pour les autres lecteurs du site qui recherchent des solutions à des problèmes similaires.
Vince Bowdren
Le programme peut lancer une exception de tableau hors limites si vous essayez d'accéder à l'index 0 de grantResults sans vérifier d'abord la longueur. C'est arrivé à mon programme. J'ai séparé l'instruction if pour grantResults comme une instruction if interne pour éviter que cela ne se produise, et cela fonctionne bien maintenant.
Peter Griffin
1

Cette réponse acceptée ne fonctionne pas pour moi, j'ai donc trouvé ma propre solution, expliquée ci-dessous:

1.J'ai d'abord créé une méthode, en fragment:

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. Et puis l'a appelé à partir de son activité sous-jacente:

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

Et ça marche ...

Biplob Das
la source
0

Vérifiez que PERMISSION_REQUEST_CODEdans onRequestPermissionsResultet à l'intérieur de votre Fragmentcontient la même valeur.

dianakarenms
la source
0

Pour le tragetSDK 28, la vérification du SDK (> 23) et les demandes d'autorisation du fragment fonctionneraient. ActivityCompat.requestPermissions échoue (si vous définissez un code de demande inférieur à 65536, la boîte de dialogue d'autorisation apparaît et si l'utilisateur autorise l'autorisation, les autorisations sont fournies, mais aucun rappel ne se produira. Mais si vous définissez au-dessus de 65536, ActivityCompat.requestPermissions échouer immédiatement. Je ne connais pas le raisonnement derrière cette logique. peut être un bogue ou intentionnel).

Code de travail:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }
Raj kannan Iyyappan
la source
vous n'avez pas besoin de faire la vérification de version. dans les versions inférieures à 23, il renverra simplement la valeur «permission accordée». Choix du développeur ici: éviter le bloc `` si '' pour plus de simplicité ou éviter l'appel de requête lorsqu'il n'est pas nécessaire
Psest328
0

J'ai eu le même problème. Votre fragment peut être initialisé à partir de la mise en page de l'activité. Comme ça:

main_activty.xml

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

Ce problème a été résolu pour moi lorsque j'ai utilisé à la FragmentTransactionplace

Bohdan Ishchenko
la source
0

dans les API inférieures à 23, vous pouvez créer une interface dans l'activité, puis l'implémenter dans le fragment enfant et lorsque vous obtenez une demande d'autorisation, l'activité la transmet à l'interface implémentée dans le fragment. C'est aussi simple :)

A.sobhdel
la source
0

vous pouvez appeler la méthode Fragment ci-dessous

@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.

}
MFQ
la source
-5

Ce problème était en fait causé par NestedFragments. Fondamentalement, la plupart des fragments que nous avons étendent un HostedFragment qui à son tour étend un CompatFragment. Le fait d'avoir ces fragments imbriqués a provoqué des problèmes qui ont finalement été résolus par un autre développeur du projet.

Il faisait des trucs de bas niveau comme la commutation de bits pour que cela fonctionne, donc je ne suis pas trop sûr de la solution finale réelle

Manikandan K
la source
3
Au lieu de copier une réponse, vous pouvez simplement fournir un lien - stackoverflow.com/a/33081173/630833
jayeffkay