studio permission permisos how for example escritura ask android android-fragments android-dialogfragment android-6.0-marshmallow

android - permisos - onRequestPermissionsResult no se llama en el fragmento de diálogo



runtime permission android studio (10)

Además de la parte final de la respuesta de Nino Handler y para cualquier persona que todavía tenga problemas con esto, asegúrese de que si anula onRequestPermissionsResult en la actividad / fragmento principal de su fragmento de diálogo, llame a super.onRequestPermissionsResult allí.

Estaba anulando onRequestPermissionsResult en la actividad principal de mi fragmento de diálogo, pero no pude llamar al método super allí. Una vez que lo cambié para llamar al súper método, lo delegó correctamente en onRequestPermissionsResult en mi fragmento de diálogo.

He comenzado a trabajar con el permiso de ejecución de Android M. Aquí me enfrento al problema de que si se llama a requestPermissions desde la clase Dialog Fragment , entonces onRequestPermissionsResult no se llama en la misma clase de Dialog fragment . Pero si se llama a requestPermissions desde la clase Activity o la clase Fragment , el método onRequestPermissionsResult se llama en la misma clase.

Aquí está mi código de muestra:

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 requestPermissions de la clase Dialog Fragment . Así que espero obtener resultados en la misma clase.

Cualquier ayuda es apreciada. ¡Gracias por adelantado!

EDITAR: Aquí estoy agregando más detalles, para que sea más útil para los demás. Anteriormente he usado getChildFragmentManager () para mostrar el DialogFragment.

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

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

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


Este issue parece estar solucionado en la Biblioteca de soporte de Android 23.3.0 y versiones superiores.

Si está utilizando fragmentos de Support v4, los fragmentos anidados ahora recibirán devoluciones de llamada a onRequestPermissionsResult ().

Editar: @AndrewS, así es como puedes actualizar.

En su archivo build.gradle (aplicación), 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'' }


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); } } }


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 que el fragmento que quiere mostrar el diálogo llame a un método en la actividad de alojamiento, y la actividad muestra el DialogFragment sí.


Si echa un vistazo a la documentación del método requestPermissions del fragmento, descubrirá que todavía tiene que declarar los permisos en su Manifiesto:

Si este no es el caso, no se invocará el propio onRequestPermissionsResult del fragmento.

En cambio, se llama a onRequestPermissionsResult la actividad pero no tendrá ningún efecto.

Por lo tanto, obtener un permiso desde un fragmento debe hacerse de la siguiente manera:

1. Declara el permiso en tu manifiesto

<uses-permission android:name="android.permission.CAMERA"/>

Ingrese esto antes de la etiqueta de la aplicación.

2. Verifique el permiso en su fragmento

if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { requestPermissions( arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_CAMERA_PERMISSION) }

3. Espere a que el permiso dé como resultado su fragmento

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { when (requestCode) { REQUEST_CODE_CAMERA_PERMISSION -> { val granted = grantResults.isNotEmpty() && permissions.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED && !ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[0]) when (granted) { true -> openCamera() else -> proceedWithoutPermission() } } }

4. Asegúrese de no anular la actividad onRequestPermissionsResult

onRequestPermissionsResult el onRequestPermissionsResult la actividad hará que el fragmento del fragmento no reaccione.



Si tiene problemas con el fragmento anidado, puede solicitar permiso del fragmento primario

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

y luego reenviar la devolución de llamada al fragmento hijo

@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); } } } }


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

Agregando
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
a la actividad onRequestPermissionsResult() resolvió el problema.


Una cosa que me ayudó fue esto. Cuando solicite permiso de un fragmento anidado, use getParent así

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

y luego anule el fragmento primario enRequestPermissionResult y verifique el requestCode correspondiente.

Espero que te ayude también.


EDITAR:

Sugiero usar una nueva versión de Support Library 23.3.0, porque Google solucionó el problema de no llamar a onRequestPermissionsResult , pero si por alguna razón necesita usar una versión anterior, consulte la respuesta de origen a continuación.

RESPUESTA ORIGINAL:

Estoy usando la próxima solución (junto con la biblioteca easyPermissions ):

Fragmento Base:

@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); } } } }

Actividad base:

@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); } }