Permisos en Android Marshmallow

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:

permisosVerificar la plataforma

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" />

5 pensamientos en “Permisos en Android Marshmallow

    • 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 gusta

  1. 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 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 gusta

Deja un comentario