onRequestPermissionsResult n’est pas appelé dans le fragment de dialog

J’ai commencé à travailler sur l’autorisation d’exécution Android M. Ici, je suis confronté au problème que si requestPermissions est appelée à partir de la classe Dialog Fragment alors onRequestPermissionsResult ne onRequestPermissionsResult pas appelé dans la même classe de Dialog fragment . Mais si requestPermissions est appelée à partir de Activity classe Activity ou de la classe Fragment , alors la méthode onRequestPermissionsResult est appelée dans la même classe.

Voici mon exemple de code:

 public class ContactPickerDialog extends DialogFragment { private static final int READ_CONTACTS_REQUEST_CODE = 12; private Context mContext; private void loadContact() { if(hasPermission(mContext, Manifest.permission.READ_CONTACTS)){ new ContactSyncTask().execute(); } else { this.requestPermissions(new Ssortingng[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int requestCode, Ssortingng[] permissions, int[] grantResults) { Logger.d("TAG", "dialog onRequestPermissionsResult"); switch (requestCode) { case READ_CONTACTS_REQUEST_CODE: // Check Permissions Granted or not if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { new ContactSyncTask().execute(); } else { // Permission Denied Toast.makeText(getActivity(), "Read contact permission is denied", Toast.LENGTH_SHORT).show(); } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } private static boolean hasPermission(Context context, Ssortingng permission){ return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED; } } 

Dans le code, requestPermissions méthode requestPermissions de la classe requestPermissions Dialog Fragment . Donc, je m’attends à obtenir un résultat dans la même classe.

Toute aide est appréciée. Merci d’avance!


EDIT: Ici, j’ajoute plus de détails, pour que cela soit plus utile aux autres. Auparavant, j’ai utilisé getChildFragmentManager () pour afficher le DialogFragment.

 ContactPickerDialog dialog = new ContactPickerDialog(); dialog.show(getChildFragmentManager(), "Contact Picker"); 

Mais comme @CommonWare m’a demandé d’utiliser l’activité pour afficher le DialogFragment. J’ai apporté les modifications suivantes et cela fonctionne.

 ContactPickerDialog dialog = new ContactPickerDialog(); dialog.show(getActivity().getSupportFragmentManager(), "Contact Picker"); 

Il semble y avoir un bogue dans Android , où les fragments nesteds ne prennent pas en charge le rappel onRequestPermissionsResult() . Pour un DialogFragment , une solution semble consister à demander au fragment de montrer la boîte de dialog d’appeler une méthode sur l’activité d’hébergement et l’activité affiche le DialogFragment lui-même.

Si vous vous trouvez dans une bibliothèque Fragment from support, appelez directement requestPermissions() , et le onRequestPermissionsResult() votre fragment sera rappelé.

Si vous appelez ActivityCompat.requestPermissions() , alors c’est l’ Activity onRequestPermissionsResult() qui sera onRequestPermissionsResult() .

Ce problème semble être résolu dans Android Support Library 23.3.0 et versions supérieures.

Si vous utilisez des fragments de support v4, les fragments nesteds recevront désormais des rappels sur onRequestPermissionsResult ().

Edit: @AndrewS, voici comment vous pouvez mettre à jour.

Dans votre fichier build.gradle (app), modifiez la ligne suivante pour utiliser la dernière bibliothèque de support 24.0.0, qui est la dernière version:

 dependencies { comstack 'com.android.support:appcompat-v7:24.0.0' } 

MODIFIER:

Je suggère d’utiliser une nouvelle version de Support Library 23.3.0, car Google a résolu le problème en n’appelant pas onRequestPermissionsResult , mais si, pour certaines raisons, vous deviez utiliser une version antérieure, consultez la réponse à l’origine ci-dessous.

RÉPONSE ORIGINALE:

J’utilise la solution de contournement suivante (avec la bibliothèque easyPermissions ):

BaseFragment:

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { /** child v4.fragments aren't receiving this due to bug. So forward to child fragments manually * https://code.google.com/p/android/issues/detail?id=189121 */ super.onRequestPermissionsResult(requestCode, permissions, grantResults); List fragments = getChildFragmentManager().getFragments(); if (fragments != null) { // it is possible that fragment might be null in FragmentManager for (Fragment fragment : fragments) { if (fragment != null) { fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); } } } } 

BaseActivity:

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { Fragment fragment = getSupportFragmentManager().findFragmentById(getFragmentContainer()) if (fragment != null) { fragment.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults); } } 

Usage:

 public class SomeFragment extends BaseFragment implements EasyPermissions.PermissionCallbacks { private static final int PICK_CONTACT = 1; private static final int READ_CONTACTS_PERM = 2; // some code @AfterPermissionGranted(READ_CONTACTS_PERM) private void pickContactWithPermissionsCheck() { if (EasyPermissions.hasPermissions(getContext(), Manifest.permission.READ_CONTACTS)) { // Have permission pickContactForResult(); } else { // Request one permission EasyPermissions.requestPermissions(this, getSsortingng(R.ssortingng.read_contacts_permission_explanation), READ_CONTACTS_PERM, Manifest.permission.READ_CONTACTS); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // FIXME problem with incorrect requestCode coming to callback for Nested fragments // More information here - https://code.google.com/p/android/issues/detail?id=189121 if (isVisible() && Arrays.asList(permissions).contains(Manifest.permission.READ_CONTACTS)) { requestCode = READ_CONTACTS_PERM; } // EasyPermissions handles the request result. EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } } 

Si vous rencontrez des problèmes avec un fragment nested, vous pouvez demander l’autorisation au fragment parent

 getParentFragment().requestPermissions(new Ssortingng[]{permission}, requestCode); 

puis transférer le rappel au fragment enfant

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grants) { List fragments = getChildFragmentManager().getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if (fragment != null) { fragment.onRequestPermissionsResult(requestCode, permissions, grants); } } } } 

Une chose qui m’a aidé était ceci. Lorsque vous demandez l’autorisation d’un fragment nested, utilisez getParent comme cela

  fragment.getParentFragment().requestPermissions((new Ssortingng[] {Manifest.permission.READ_CONTACTS}), requestCode); 

puis remplacez le fragment parent onRequestPermissionResult et recherchez le requestCode correspondant.

J’espère que cela vous aidera aussi.

J’ai eu ce problème sans fragments nesteds, où l’activité montrait le fragment de dialog et le résultat n’était pas passé.

Ajouter
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
à l’activité onRequestPermissionsResult() résolu le problème.

Je l’ai fait comme ça

 public class DialogFragmentSMS extends DialogFragment implements View.OnClickListener { public static DialogFragmentSMS frag; private static View view; private static ViewGroup parent; private EditText editTextMensagem; private Ssortingng celular; private final static int SMS_REQUEST = 20; public DialogFragmentSMS() { } public static DialogFragmentSMS newInstance(Ssortingng celular) { Bundle args = new Bundle(); args.putSsortingng("celular", celular); frag = new DialogFragmentSMS(); frag.setArguments(args); return frag; } @Override public void onCreate(Bundle saveInstaceState) { super.onCreate(saveInstaceState); } @Override public void onClick(View v) { if (!PermissaoUtils.hasPermission(getActivity(), Manifest.permission.SEND_SMS)) { //PermissaoUtils.requestPermissions(getActivity(), new Ssortingng[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); frag.requestPermissions(new Ssortingng[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); }else{ if (validaCampos()) { SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage("0" + celular, null, editTextMensagem.getText().toSsortingng(), null, null); Toast.makeText(getActivity(), R.ssortingng.sms_enviado, Toast.LENGTH_SHORT).show(); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); frag.dismiss(); } } } 

Ma permission de classe

 public class PermissaoUtils { public static boolean useRunTimePermissions() { return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; } public static boolean hasPermission(Activity activity, Ssortingng permission) { if (useRunTimePermissions()) { return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } return true; } public static void requestPermissions(Activity activity, Ssortingng[] permission, int requestCode) { if (useRunTimePermissions()) { activity.requestPermissions(permission, requestCode); } } } 

Si vous appelez DialogFragment à partir d’un fragment, utilisez ceci:

 YourDialogFragment dialogFragment = YourDialogFragment.newInstance(); dialogFragment.show(getActivity().getFragmentManager(), YourDialogFragment.TAG); dialogFragment.setParentFragment(this); 

Également écrire dans le fragment:

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull Ssortingng[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { ... } } 

Dans YourDialogFragment, écrivez une méthode supplémentaire pour transmettre un fragment parent:

 public void setParentFragment(Fragment fragment) { this.fragment = fragment; } 

Plus tard dans YourDialogFragment, lorsque vous demandez des permissions, appelez:

 if (fragment != null) { fragment.requestPermissions(new Ssortingng[]{permission}, REQUEST_CODE); }