java - support - cómo solicitar permisos durante el tiempo de ejecución
Solicite permisos de tiempo de ejecución de v4.Fragment y haga que la devolución de llamada vaya a Fragment? (10)
Agregar esto a la actividad principal funciona para mí:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Fuente: https://code.google.com/p/android/issues/detail?id=189121#c5
Tengo un problema extraño que está causando un conflicto.
Tuve que cambiar a
Fragments
nativos para solucionarlo, pero hay errores con eso.
Mi problema original: tengo una configuración de cajón de navegación con
v4 Fragments.
Para solicitar permiso en uno de mis Fragmentos, llamo a
ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1);
El mensaje aparece muy bien, pero cuando acepto o niego el permiso, no sucede nada.
La devolución de llamada
onRequestPermissionsResult()
nunca se llama.
En su lugar, se llama en la Actividad a la que están unidos mis Fragmentos.
Inútil para mí, necesito la devolución de llamada para trabajar en el Fragmento.
Con esto en mente, me dijeron que necesitaba usar
FragmentCompat
, pero que solo funciona con
native Fragments (v13+)
, así que cambié el cajón de navegación para trabajar desde Fragmentos nativos en lugar de los Fragmentos de la biblioteca de soporte v4.
Sin embargo
, debido a que estoy usando AppCompatActivity, ciertas cosas no funcionan, como
addToBackStack()
y volver a un fragmento anterior.
En pocas palabras, ¿alguien sabe cómo puedo usar el
v4.Fragment
y aún pedir permiso en el
Fragment
y obtener la devolución de llamada para estar en el
Fragment
?
Siento que este es un error en Android que no se ha abordado, pero no estoy al 100%.
Avíseme si necesita ver mi código, son solo los métodos estándar que necesita para los permisos de tiempo de ejecución, aunque me gustaría trabajar con Fragmentos v4, lo que no funciona desde mi entendimiento.
En mi caso, solicité el permiso del fragmento y también necesito obtener la respuesta en el fragmento.
Pero mi teléfono se ejecuta en Android 8.1
así que tuve que agregar una condición más para verificar esto
entonces eventualmente esta mi solución
private void doOnWazeButtonClick()
{
int permissionStatus = PackageManager.PERMISSION_DENIED;
if (getContext() != null)
{
permissionStatus = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionStatus == PackageManager.PERMISSION_GRANTED)
{
showContentWaze();
}
else
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
Objects.requireNonNull(getActivity()).requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
}
else
{
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
}
}
}
Este comportamiento parece estar presente en la clase de soporte v4 Fragment requestPermissions in Fragment . Las implementaciones de Activity / FragmentCompat existen para las personas que desean usar las clases nativas con la funcionalidad extendida en niveles de API entre 11 y 23.
No sé si Google lo solucionó recientemente, pero puedo alcanzar el resultado esperado sin hacer ningún truco.
Lo más importante es llamar a
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
en la actividad, por lo que pasará el resultado al fragmento si se solicita desde el fragmento.
Entonces, lo que hago es:
1) en fragmento, solicite permiso usando
v4 fragment.requestPermissions(permissions, requestCode)
2) en la actividad onRequestPermissionsResult, debe llamar a
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
3) en el fragmento onRequestPermissionsResult, escriba el código que quiero manejar el resultado.
Por el momento, la solución más estable es hacerlo a mano. Yo mismo lo resolví simplemente notificando fragmentos secundarios de los fragmentos principales.
if (fragment.getParentFragment() != null) {
Fragment parentFragment = fragment.getParentFragment();
try {
ChildFragmentPermissionRegistry registry = (ChildFragmentPermissionRegistry) parentFragment;
registry.registerPermissionListener((ChildFragmentPermissionCallback) fragment);
parentFragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
} catch (ClassCastException e) {
Log.e(PermissionVerifier.class.getSimpleName(), e.getMessage());
}
} else {
fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
}
Donde el fragmento primario implementa la interfaz ChildFragmentPermissionRegistry y registra el fragmento secundario,
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (callback != null) {
callback.onRequestPermissionsResult(requestCode, permissions, grantResults);
callback = null;
}
}
y fragmentos secundarios implementa ChildFragmentPermissionCallback
e interfaces son algo como esto:
public interface ChildFragmentPermissionCallback {
void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}
public interface ChildFragmentPermissionRegistry {
void registerPermissionListener(ChildFragmentPermissionCallback callback);
}
Puedes usar esta parte del código
requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);
Recientemente enfrenté la misma situación, cuando necesitaba verificar un permiso dentro del fragmento de soporte y recibir una devolución de llamada allí.
Pude usar
ContextCompat
para
checkSelfPermission
y luego, como dijo @NasaGeek, llamé a
android.support.v4.app.Fragment
''s
requestPermissions
para solicitar el permiso y luego volví a llamar a
onRequestPermissionsResult
en v4 Fragment.
Espero que esto ayude.
Gracias.
Si necesita obtener el permisoResultar en el
fragment v4
asegúrese de usar
Fragment.requestPermission(String[], int);
en lugar de
AppCompat.requestPermission(Activity, String[], int)
¡Mira this respuesta!
Simplemente use requestPermission ("su permiso / s en una matriz de cadenas", su código de solicitud) simplemente no necesita usar
Fragment.requestPermissons(String[],int );
Este método en su fragmento llama a requestPermissions de
android.support.v4.app.Fragment class ie
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
if (mHost == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
}
mHost.onRequestPermissionsFromFragment(this, permissions, requestCode);
}
v4.Fragment funciona bien. Tengo un problema con el fragmento anidado de v4.Fragment. Se solicita permiso, ¡pero la devolución de llamada onRequestPermissionsResult () nunca se llama en un fragmento anidado!