La versión 6.0 de Android incluye un nuevo modo de gestionar los permisos de las aplicaciones. En esta versión, en vez de solicitar todos los permisos necesarios al instalar una aplicación, se van solicitando en tiempo de ejecución cuando es necesario utilizarlos. De este modo, se evitan posibles rechazos por parte del usuario a la hora de instalar la aplicación si ésta necesita muchos permisos, y además le aporta conocimiento de dónde se va a usar cada uno de ellos, permitiendo seleccionar solo los que le interese (en tiempo de ejecución o mediante la pantalla de configuración de aplicaciones).
El flujo que deberíamos seguir para gestionar los permisos es el siguiente:
Habrá que comprobar si la versión Android es Marshmallow o anterior.
Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP
Si usarmos las librerías de soporte para versiones anteriores, no será necesario comprobar la versión.
Comprobar el permiso
En Android se distingue entre permisos normales y peligrosos. Los peligrosos son los que acceden a datos sensibles del sistema o del usuario y son los que deberá aprobar el usuario. Cada vez que se necesite uno de estos permisos, habrá que comprobar su estado aunque se hubiera utilizado antes, porque se puede haber deshabilitado después de su uso.
ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA);
checkSelfPermission() puede devolver los valores:
– PackageManager.PERMISSION_GRANTED = 0
– PackageManager.PERMISSION_DENIED = 1
Explicar el permiso
Cuando sea recomendable activar un permiso para el uso de la aplicación, deberemos mostrar una explicación de por qué es beneficioso. Para ayudarnos a determinar si se debe mostrar o no dicha explicación tenemos el método shouldShowRequestPermissionRationale, que devolverá:
– false si está desabilitado porque el dispositivo prohíba a la aplicación tener ese permiso o si el usuario dijo que no quería que se le solicitara más el permiso.
– true si el usuario rechazó el permiso pero está intentando acceder de nuevo a la parte de la aplicación que lo necesita.
ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)
Solicitar el permiso
Para solicitar el permiso utilizamos el método requestPermissions, al que deberemos pasarle un array con los permisos solicitados y un código indicado por nosotros para identificar la solicitud del permiso (REQUEST_CODE_CAMERA en el ejemplo).
requestPermissions(new String[] {Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA);
Hasta aquí, el código queda así:
// Comprobar permiso
int permissionCheck = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
abrirCamara();
} else {
// Explicar permiso
if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
Toast.makeText(getContext(), "El permiso es necesario para utilizar la cámara.",
Toast.LENGTH_SHORT).show();
}
// Solicitar el permiso
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA);
Manejar la respuesta
Cuando el usuario responde a la solicitud del permiso, se invoca el método onRequestPermissionResult. Entre los parámetros que recibe, se encuentra el código que indicamos en el paso anterior para identificar el permiso (requestCode).
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_CAMERA:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
// Permiso aceptado
abrirCamara();
else
// Permiso denegado
Toast.makeText(getContext(), "No se ha aceptado el permiso", Toast.LENGTH_SHORT).show();
return;
// Gestionar el resto de permisos
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Test
Por último, tendremos que probar todas las casuísticas. Para ello, adb nos permite manejar los permisos desde línea de comandos.
Listar permisos y su estado por grupos:
>adb shell pm list permissions -d -g
Dar o rechazar uno o más permisos:
>adb shell pm grant
>adb shell pm revoke
Además de estos pasos, no debemos olvidar añadir los permisos en el AndroidManifest:
<uses-permission android:name="android.permission.CAMERA" />
Que sucede si el usuario decide negar los permisos los cuales son fundamentales para la app, como vuelvo a mostrar el mensaje sin que se detenga la app.
Saludos
Me gustaMe gusta
La decisión de cuando se debe solicitar un permiso la tienes tú en todo momento. El método shouldShowRequestPermissionRationale se utiliza para evitar estar mostrando continuamente al usuario la pregunta de si quiere habilitar el permiso. Si en tu caso crees que es necesario mostrar siempre ese mensaje porque si no la aplicación no va a funcionar, no utilices este método y solicita el permiso con requestPermissions siempre que sea necesario. Lo que es recomendable es, que si el usuario rechazó antes el permiso, le expliques de forma clara y concisa por qué necesita habilitarlo.
Me gustaMe gusta
Hola .
Genial el artículo, muchas gracias . Pero hay una cosa que no entiendo:
«…Si usarmos las librerías de soporte para versiones anteriores, no será necesario comprobar la versión…»
Me pregunto ¿Porqué no hay que comprabar la versión en esos casos?
Me gustaMe gusta
Si no usas la librería, compruebas la versión porque solo vas a poder hacer la gestión de permisos con Marshmallow. Las librerías de soporte te van a permitir hacer esa gestión tanto en Marshmallow como en versiones anteriores, por eso no hace falta ver que versión es, va a funcionar igual en cualquiera.
Me gustaMe gusta
Haaahahh. I’m not too bright today. Great post!
Me gustaMe gusta