OnRequestPermissionsResult no se llama en el fragmento de diálogo

He empezado a trabajar en el permiso de ejecución de Android M. Aquí estoy frente a la cuestión de que si requestPermissions se llama desde la clase Dialog Fragment entonces onRequestPermissionsResult no se llama en la misma clase de Dialog fragment . Pero si requestPermissions se llama desde la clase Activity o la clase Fragment , entonces el método onRequestPermissionsResult es llamado en la misma clase.

Aquí está mi código de ejemplo:

 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 String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACTS_REQUEST_CODE); } } @Override public void onRequestPermissionsResult(int requestCode, String[] 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, String permission){ return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED; } } 

Aquí en el código estoy llamando requestPermissions método de Dialog Fragment clase. Así que espero obtener resultados en la misma clase.

Cualquier ayuda es apreciada. ¡Gracias por adelantado!


EDIT: Aquí estoy añadiendo más detalles, por lo que será más útil a los demás. Anteriormente he utilizado getChildFragmentManager () para mostrar el DialogFragment.

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

Pero como @CommonWare me pidió que usara la actividad para mostrar el DialogFragment. He hecho los siguientes cambios y funciona.

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

Parece que hay un error en Android , donde los fragmentos anidados no admiten la devolución de llamada onRequestPermissionsResult() . Para un DialogFragment , una solución parece ser tener el fragmento que desea mostrar la llamada de diálogo un método en la actividad de alojamiento y la actividad muestra el DialogFragment sí.

Si está dentro de un Fragment de la biblioteca de soporte, llame a requestPermissions() directamente, y onRequestPermissionsResult() su Fragmento será llamado de nuevo.

Si llama a ActivityCompat.requestPermissions() , entonces es onRequestPermissionsResult() que se devolverá.

Este problema parece estar corregido en Android Support Library 23.3.0 y versiones anteriores.

Si utiliza Fragmentos de Support v4, los fragmentos anidados recibirán devoluciones de llamada a onRequestPermissionsResult ().

Editar: @AndrewS, aquí es cómo puede actualizar.

En su archivo build.gradle (app), cambie la siguiente línea para usar la última biblioteca de soporte 24.0.0 que es la última versión:

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

Si tiene problema con el fragmento anidado, puede solicitar permiso del fragmento de origen

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

Y luego reenviar la devolución de llamada al fragmento secundario

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

Una cosa que me ayudó fue esto. Cuando solicita permiso de un fragmento anidado use getParent como si

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

Y luego reemplazar el fragmento padre onRequestPermissionResult y comprobar el correspondiente requestCode.

Espero que te ayude también.

EDITAR:

Sugiero usar una nueva versión de Support Library 23.3.0, porque Google corrigió el problema con no llamar a onRequestPermissionsResult , pero si por alguna razón necesitas usar una versión anterior, entonces vea la respuesta de origen a continuación.

RESPUESTA ORIGINAL:

Estoy usando la siguiente solución (junto con la biblioteca de easyPermissions ):

BaseFragment:

 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] 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<Fragment> 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 String[] permissions, @NonNull int[] grantResults) { Fragment fragment = getSupportFragmentManager().findFragmentById(getFragmentContainer()) if (fragment != null) { fragment.onRequestPermissionsResult(requestCode&0xff, permissions, grantResults); } } 

Uso:

 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, getString(R.string.read_contacts_permission_explanation), READ_CONTACTS_PERM, Manifest.permission.READ_CONTACTS); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] 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); } } 

Tuve este problema sin fragmentos anidados, donde la actividad estaba mostrando el fragmento de diálogo y el resultado no se estaba pasando.

Añadiendo
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
A onRequestPermissionsResult() la Actividad resolvió el problema.

Lo hice así

 public class DialogFragmentSMS extends DialogFragment implements View.OnClickListener { public static DialogFragmentSMS frag; private static View view; private static ViewGroup parent; private EditText editTextMensagem; private String celular; private final static int SMS_REQUEST = 20; public DialogFragmentSMS() { } public static DialogFragmentSMS newInstance(String celular) { Bundle args = new Bundle(); args.putString("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 String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); frag.requestPermissions(new String[]{Manifest.permission.SEND_SMS}, SMS_REQUEST); }else{ if (validaCampos()) { SmsManager smsManager = SmsManager.getDefault(); smsManager.sendTextMessage("0" + celular, null, editTextMensagem.getText().toString(), null, null); Toast.makeText(getActivity(), R.string.sms_enviado, Toast.LENGTH_SHORT).show(); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); frag.dismiss(); } } } 

Mi permiso de clase

 public class PermissaoUtils { public static boolean useRunTimePermissions() { return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; } public static boolean hasPermission(Activity activity, String permission) { if (useRunTimePermissions()) { return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } return true; } public static void requestPermissions(Activity activity, String[] permission, int requestCode) { if (useRunTimePermissions()) { activity.requestPermissions(permission, requestCode); } } } 
  • Aplicación cerrada después de hacer clic en el botón Atrás en Fragmento
  • OnCreateOptionsMenu () en el fragmento que no reemplaza los menús de ActionBar
  • Enviar paquete con transacción de fragmentos
  • Ver reutilización en fragmentos android
  • Tabs + ViewPager + FragmentStatePagerAdapter - ¿Cómo eliminar el fragmento?
  • Fragmento getArguments () devuelve null
  • Mostrar un DialogFragment una vez y sólo una vez
  • Dilema: cuándo utilizar Fragmentos vs Actividades:
  • Android Studio y android.support.v4.app.Fragment: no se puede resolver el símbolo
  • ¿Cómo puedo acceder a getSupportFragmentManager () en un fragmento?
  • java.lang.IllegalStateException (No se puede realizar esta acción después de onSaveInstanceState)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.