onRequestPermissionsResult no se llama en fragmento si se define tanto en fragmento como en actividad


167

Tengo un fragmento en el que tengo vista de reciclaje y datos de configuración en esta vista de reciclaje usando el adaptador de vista de reciclaje.

Ahora, tengo un botón en el elemento de la lista del adaptador haciendo clic en el cual necesito verificar el permiso READ_EXTERNAL_STORAGE en Android para obtener un nuevo modelo de permiso en Android.

He creado una nueva función en el fragmento de este adaptador para verificar si se otorga el permiso o no y solicitar permiso si ya no se ha otorgado.

He pasado MyFragment.this como parámetro en el adaptador y llamando al método del fragmento al hacer clic en el botón en el adaptador.

He usado el siguiente código para llamar a requestPermission en fragmento.

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

He anulado el onRequestPermissionsResultmétodo fragmentado usando el siguiente código:

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

Pero no se llama, en lugar del método onRequestPermissionsResult de esta actividad se llama.

También he definido el mismo método onRequestPermissionsResult en la actividad principal del fragmento y se está llamando.

No puedo eliminar el método onRequestPermissionsResult de la actividad, pero quiero llamar al método onRequestPermissionsResult del fragmento cuando solicito permiso del fragmento. ¿Cómo puedo hacer esto? ¿Estoy haciendo algo mal aquí? Ayúdenme si alguien tiene una idea aquí.


1
consulte este enlace permisos de tiempo de ejecución en fragmentos Esta es la solución exacta
Antony jackson

Respuestas:


372

Respuesta editada para cubrir problemas más amplios

Creo que estás confundiendo el método para el fragmento y la actividad. Tuve un problema similar en mi proyecto el mes pasado. Por favor, compruebe si finalmente tiene lo siguiente:

  1. En AppCompatActivity use el método ActivityCompat.requestpermissions
  2. En el fragmento de soporte v4, debe usar permisos de solicitud
  3. La captura es si llama a AppcompatActivity.requestpermissions en su fragmento, la devolución de llamada se activará y no se fragmentará
  4. Asegúrese de llamar super.onRequestPermissionsResultdesde la actividad onRequestPermissionsResult.

A ver si ayuda.


9
Solo para verificar dos veces, asegúrese de tener un resultado super.onrequestpermission establecido en su actividad
VarunJoshi129

27
Al agregar super.onrequestpermissionresultel resultado onrequestpermission de la actividad, llame al resultado onrequestpermissionresultado del fragmento cuando solicito permiso para usar requestpermissions. Esto está funcionando bien ahora, muchas gracias .. :)
Prithniraj Nicyone

1
El super.onrequestpermissionresult le faltaba a la devolución de llamada actividad, lo que lleva a mi devolución de llamada fragmento de no conseguir llamada
Sakis kaliakoudas

44
requestPermissions () requiere API nivel 23. ¿Hay otra solución que sea compatible con versiones anteriores para API nivel 21?
Adam Hurwitz

2
@ msc87 1. en onRequestPermissionsResult de actividad y fragmento, la primera línea debe ser: super.onRequestPermissionsResult (requestCode, permissions, grantResults); 2.en el fragmento donde se reconoce el permiso no otorgado, simplemente llame al método requestPermission de esta manera: requestPermissions (nueva cadena [] {Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
AREF

122

Solicité permiso de ubicación de un fragmento y en el fragmento, necesitaba cambiar esto:

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

a esto:

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

entonces se llamó a onRequestPermissionsResult en el fragmento.


2
Funciona como un encanto :)
Antonio Vlasic

1
no está funcionando con kotlin, ¿pueden ayudarme por lo mismo? Aquí se usa esta solicitud Permisos (contexto como Activity, permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

Gracias :), me ahorras tiempo
Axrorxo'ja Yodgorov

19

Este es un error común que la gente comete al codificar malvavisco.

Cuando esté en AppCompatActivity, debe usar ActivityCompat.requestPermissions; Cuando esté en android.support.v4.app.Fragment, debe usar simplemente requestPermissions (este es un método de instancia de android.support.v4.app.Fragment) Si llama a ActivityCompat.requestPermissions en un fragmento, se llama a la devolución de llamada onRequestPermissionsResult la actividad y no el fragmento

requestPermissions(permissions, PERMISSIONS_CODE);

Si está llamando a este código desde un fragmento, tiene su propio método requestPermissions.

Entonces, el concepto básico es: si está en una actividad, llame al

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

y si está en un fragmento, solo llame

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

Para la referencia, obtuve la respuesta de este enlace https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

El método requestPermissionsen Fragments requiere un nivel de API 23 o superior.
Si su aplicación está dirigida a una versión inferior, puede usar

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

Primero debe agregar la dependencia support-v13:

implementation "com.android.support:support-v13:$supportLibVersion"

FragmentCompat está en desuso de la versión 27.1.0
Raj kannan Iyyappan el

6

cambia esto :

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

a esto :

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

La inferior es para usar en un fragmento (onRequestPermissionsResult se llama en fragmento), la versión ActivityCompat se usa cuando onRequestPermissionsResult se ubica en la Actividad.
Rugido Grønmo

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

cambiar permiso


2
Hola usuario2002721; su código puede ser correcto, pero con algún contexto sería una mejor respuesta; por ejemplo, podría explicar cómo y por qué este cambio propuesto resolvería el problema del interlocutor, tal vez incluyendo un enlace a la documentación relevante. Eso lo haría más útil para ellos, y también más útil para otros lectores del sitio que buscan soluciones a problemas similares.
Vince Bowdren

El programa podría arrojar una excepción de matriz fuera de límites si intenta acceder al índice 0 de grantResults sin verificar primero la longitud. Le pasó a mi programa. Separé la declaración if para grantResults como una declaración if interna para evitar que eso suceda, y ahora funciona bien.
Peter Griffin

1

Esta respuesta aceptada no me funcionó, así que encontré mi propia solución, que se explica a continuación:

1.Primero creé un método, en fragmento:

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. Y luego lo llamó desde su actividad subyacente:

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

Y está funcionando ...


0

Verifique que tanto PERMISSION_REQUEST_CODEdentro onRequestPermissionsResultcomo dentro de su Fragmentcontiene el mismo valor.


0

Para el tragetSDK 28, la verificación SDK (> 23) y los permisos de solicitud del fragmento funcionarían. ActivityCompat.requestPermissions está fallando (si establece el código de solicitud por debajo de 65536, aparecerá el cuadro de diálogo de permiso y si el usuario lo permite, se otorgan los permisos, pero no se producirá una devolución de llamada. Pero si establece por encima de 65536, ActivityCompat.requestPermissions aparecerá falla inmediatamente. No sé el razonamiento detrás de esta lógica. Puede ser un error o intencional).

Código de trabajo:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }

No es necesario que verifique la versión. en versiones inferiores a 23, solo devolverá el valor de "permiso otorgado". Elección del desarrollador aquí: evite el bloque 'if' por simplicidad o evite la llamada de solicitud cuando no sea necesario
Psest328 9/18


0

Tuve el mismo problema. Su fragmento se puede inicializar desde el diseño de la actividad. Como eso:

main_activty.xml

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

Este problema se solucionó para mí cuando he usado FragmentTransactionen vez


0

en las API inferiores a 23, puede crear una interfaz en la actividad, luego implementarla en el fragmento secundario y, cuando obtiene la solicitud de permiso, la actividad la pasa a la interfaz implementada en fragmento. Es así de simple :)


0

puedes llamar al método Fragment a continuación

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

}

-5

Este problema fue causado realmente por NestedFragments. Básicamente, en la mayoría de los fragmentos hemos extendido un HostedFragment que a su vez extiende un CompatFragment. Tener estos fragmentos anidados causó problemas que finalmente fueron resueltos por otro desarrollador en el proyecto.

Estaba haciendo algunas cosas de bajo nivel, como el cambio de bits para que esto funcione, así que no estoy muy seguro de la solución final real


3
En lugar de copiar una respuesta, puede proporcionar un enlace - stackoverflow.com/a/33081173/630833
jayeffkay
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.