Skip to content

Most visited

Recently visited

navigation

Cómo solicitar permisos durante el tiempo de ejecución

En esta lección, aprenderás a realizar lo siguiente:

Dependencias y requisitos previos

  • Android 6.0 (nivel de API 23)

También debes leer:

A partir de Android 6.0 (nivel de API 23), los usuarios conceden permisos a las apps mientras se ejecutan, no cuando instalan la app. Este enfoque simplifica el proceso de instalación de la app, ya que el usuario no necesita conceder permisos cuando instala o actualiza la app. También brinda al usuario mayor control sobre la funcionalidad de la app; por ejemplo, un usuario podría optar por proporcionar a una app de cámara acceso a esta, pero no a la ubicación del dispositivo. El usuario puede revocar los permisos en cualquier momento desde la pantalla de configuración de la app.

Los permisos del sistema se dividen en dos categorías, normal y riesgoso:

Para obtener más información, consulta Permisos normales y peligrosos.

En todas las versiones de Android, tu app debe declarar los permisos normales y peligrosos que necesita en su manifiesto, como se describe en Declaración de permisos. No obstante, el efecto de esa declaración es diferente según la versión del sistema y el nivel de SDK de destino de tu app:

Nota: A partir de Android 6.0 (nivel de API 23), los usuarios pueden revocar permisos desde cualquier app en cualquier momento, aunque la app esté orientada a un nivel de API inferior. Debes probar tu app para verificar que se comporte correctamente cuando no cuente con un permiso necesario, independientemente del nivel de API al que esté orientada tu app.

En esta lección se describe la manera de usar la biblioteca de compatibilidad de Android para comprobar la existencia de permisos y solicitarlos. El framework de Android ofrece métodos similares a partir de Android 6.0 (nivel de API 23). Sin embargo, el uso de la biblioteca de compatibilidad es más simple, ya que tu app no necesita verificar la versión de Android que esté en ejecución antes de llamar a los métodos.

Comprobar si existen permisos

Si tu app necesita un permiso riesgoso, debes verificar si tienes ese permiso cada vez que realices una operación que lo requiera. El usuario siempre puede revocar el permiso. Por lo tanto, aunque la app haya usado la cámara el día anterior, no puede suponer que seguirá teniendo ese permiso para el día en curso.

Para comprobar si tienes un permiso, llama al método ContextCompat.checkSelfPermission(). Por ejemplo, en este fragmento se muestra la manera de comprobar si la actividad tiene permiso para realizar operaciones de escritura en el calendario:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

Si la app tiene el permiso, el método muestra PackageManager.PERMISSION_GRANTED y esta puede continuar con la operación. Si la app no tiene el permiso, el método muestra PERMISSION_DENIED y la app debe solicitar permiso al usuario de manera explícita.

Solicitar permisos

Si tu app necesita un permiso riesgoso indicado en el manifiesto, debe solicitar al usuario que lo otorgue. Android ofrece varios métodos que puedes usar para solicitar un permiso. Cuando llamas a estos métodos, aparece un diálogo de Android estándar que no se puede personalizar.

Explica la razón por la cual la app necesita permisos

Figura 1: Diálogo del sistema en el que se solicita al usuario otorgar o rechazar un permiso.

En algunas circunstancias, te recomendamos ayudar al usuario a comprender por qué tu app necesita un permiso. Por ejemplo, si un usuario inicia una app de fotografía probablemente no se sorprenda si la app le solicita permiso para usar la cámara. Sin embargo, es posible que el usuario no comprenda por qué la app busca acceder a la ubicación o los contactos del usuario. Antes de solicitar un permiso, debes considerar brindar una explicación al usuario. Recuerda que no te convendrá abrumar al usuario con explicaciones; si lo haces, el usuario podría sentirse frustrado y eliminar la app.

Un enfoque que podrías usar consiste en proporcionar una explicación solo si el usuario rechaza la solicitud de permiso. Si el usuario continúa intentando usar una funcionalidad que requiere un permiso, pero sigue rechazando la solicitud de permiso, esto probablemente nos indique que no comprenda por qué la app necesita el permiso para proporcionar esa funcionalidad. En una situación como esta, probablemente te convenga mostrar una explicación.

Para ayudar a detectar situaciones en las cuales el usuario podría necesitar una explicación, Android proporciona un método de utilidad: shouldShowRequestPermissionRationale(). Este método muestra true si la app solicita el permiso anteriormente y el usuario rechaza la solicitud.

Nota: Si el usuario rechaza la solicitud de permiso en el pasado y selecciona la opción Don't ask again en el diálogo de solicitud de permiso del sistema, el método muestra false. También muestra false si una política de dispositivo prohíbe que la app tenga ese permiso.

Solicitar los permisos que se necesitan

Si tu app todavía no tiene el permiso que necesita, debe llamar a uno de los métodos requestPermissions() para solicitar los permisos correspondientes. Tu app pasa los permisos que necesita y también un código de solicitud de entero que tú especificas para identificar esta solicitud de permiso. Este método funciona de manera asincrónica: realiza la devolución inmediatamente y, cuando el usuario responde al cuadro de diálogo, el sistema llama al método callback de la app con los resultados y pasa el mismo código de solicitud que la app le pasó a requestPermissions().

El siguiente código verifica si la app tiene permiso para leer los contactos del usuario y solicita el permiso si es necesario:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

Nota: Cuando tu app llama a requestPermissions(), el sistema muestra al usuario un cuadro de diálogo estándar. Tu app no puede configurar ni modificar ese cuadro de diálogo. Si necesitas proporcionar información o una explicación al usuario, debes hacerlo antes de llamar a requestPermissions(), como se describe en Explica la razón por la cual la necesita permisos.

Controla la respuesta a la solicitud de permisos

Cuando tu app solicita permisos, el sistema muestra al usuario un cuadro de diálogo. Cuando el usuario responde, el sistema invoca el método onRequestPermissionsResult() de tu app y le pasa la respuesta del usuario. Tu app debe anular ese método para averiguar si se otorgó el permiso. El callback recibe el mismo código de solicitud que le pasaste a requestPermissions(). Por ejemplo, si una app solicita acceso a READ_CONTACTS, es posible que tenga el siguiente método callback:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

El cuadro de diálogo que muestra el sistema describe el grupo de permisos al que tu app necesita acceder, pero no indica el permiso específico. Por ejemplo, si solicitas el permiso READ_CONTACTS, el cuadro de diálogo del sistema simplemente indica que tu app necesita acceder a los contactos del dispositivo. El usuario solo debe otorgar el permiso una vez para cada grupo de permisos. Si tu app requiere otros permisos de ese grupo (que se indican en el manifiesto de tu app), el sistema los concede automáticamente. Cuando solicitas el permiso, el sistema llama a tu método callback onRequestPermissionsResult() y pasa PERMISSION_GRANTED, de la misma manera en que lo haría si el usuario hubiera aceptado explícitamente tu solicitud a través del cuadro de diálogo del sistema.

Nota: Tu app debe, de todos modos, solicitar explícitamente cada uno de los permisos que necesita aunque el usuario haya otorgado otro del mismo grupo. Además, la agrupación de permisos puede cambiar en futuras versiones de Android. En tu código no debe presuponerse que habrá o no permisos específicos en el mismo grupo.

Por ejemplo, supón que indicas READ_CONTACTS y WRITE_CONTACTS en el manifiesto de tu app. Si solicitas READ_CONTACTS, el usuario concede el permiso y luego solicitas WRITE_CONTACTS, el sistema te otorga de inmediato ese permiso sin interactuar con el usuario.

Si un usuario rechaza una solicitud de permiso, tu app debe tomar una medida adecuada. Por ejemplo, tu app podría mostrar un diálogo en el que se explique por qué no podría realizar la acción solicitada por el usuario para la cual se requiere ese permiso.

Cuando el sistema solicita al usuario que otorgue un permiso, el usuario tiene la opción de indicar al sistema que no solicite ese permiso de nuevo. En ese caso, cuando la app use requestPermissions() para solicitar ese permiso nuevamente, el sistema rechazará la solicitud de inmediato. El sistema llama a tu método callback PERMISSION_DENIED y pasa onRequestPermissionsResult(), de la misma manera en que lo haría si el usuario hubiera rechazado explícitamente tu solicitud una vez más. Esto significa que cuando llamas a requestPermissions(), no puedes suponer que haya existido interacción directa con el usuario.

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)