page.title=Permisos page.tags=recursos de la versión preliminar, androidm page.keywords=permisos, tiempo de ejecución, vista preliminar page.image={@docRoot}preview/features/images/permissions_check.png @jd:body

Quickview

Contenido del documento

  1. Información general
  2. Codificación para permisos de tiempo de ejecución
  3. Prueba de permisos de tiempo de ejecución
  4. Mejores prácticas

M Developer Preview introduce un nuevo modelo de permisos de la aplicación que facilita a los usuarios el proceso de instalación y actualización de aplicaciones. Si una aplicación que se ejecuta en la versión preliminar de Android M es compatible con el nuevo modelo de permisos, el usuario no tiene que conceder ningún permiso al instalar o actualizar la aplicación. En su lugar, la aplicación solicitará los permisos a medida que los vaya necesitado y el sistema mostrará al usuario un diálogo en el que le solicitará los permisos necesarios.

Si la aplicación es compatible con el nuevo modelo de permisos, podrá instalarse y ejecutarse en los dispositivos con versiones anteriores de Android, utilizando el modelo de permisos anterior en esos dispositivos.

Información general

En M Developer Preview, la plataforma introduce un nuevo modelo de permisos de la aplicación. A continuación, se presenta un resumen de los componentes principales de este nuevo modelo:

Este modelo de permisos cambia la forma en la que la aplicación se comporta para características que requieren permisos. A continuación, se presenta un resumen de las prácticas de desarrollo que debe seguir para ajustarse a este modelo:

Nota: Si una aplicación tiene como destino M Developer Preview, debe utilizar el nuevo modelo de permisos.

A partir del lanzamiento de M Developer Preview, no todas las aplicaciones de Google implementarán por completo el nuevo modelo de permisos. Google actualiza estas aplicaciones durante el transcurso de M Developer Preview para respetar adecuadamente las configuraciones de alternancia de los permisos.

Nota: Si la aplicación cuenta con su propia superficie de API, no transmita permisos sin antes asegurarse de que el iniciador de la llamada cuente con los permisos requeridos para acceder a esa información.

Permisos de las aplicaciones de firma y de sistema

Generalmente, cuando el usuario instala una aplicación, el sistema solo otorga a la aplicación {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}. Sin embargo, en ciertas circunstancias, el sistema le concede a la aplicación más permisos:

En ambos casos, el usuario aún puede revocar los permisos en cualquier momento si accede a la pantalla Settings del sistema y selecciona Apps > app_name > Permissions. La aplicación debe seguir controlando los permisos al momento de la ejecución y solicitarlos si fuese necesario.

Compatibilidad con modelos anteriores y posteriores

Si una aplicación no tiene como destino M Developer Preview, la aplicación continúa utilizando el modelo de permisos anterior, incluso en dispositivos con la versión preliminar de Android M. Cuando el usuario instala la aplicación, el sistema le solicita al usuario que otorgue todos los permisos enumerados en el manifiesto de la aplicación.

Nota: En dispositivos que ejecutan M Developer Preview, el usuario puede desactivar los permisos para cualquier aplicación (incluso para aplicaciones heredadas) desde la pantalla Settings de la aplicación. Si un usuario desactiva permisos para una aplicación heredada, el sistema desactiva las funciones correspondientes de forma automática. Cuando la aplicación intenta realizar una operación que requiere ese permiso, la operación no generará necesariamente una excepción. En su lugar, devolverá un conjunto de datos vacíos, indicará un error o, de lo contrario, mostrará un comportamiento inesperado. Por ejemplo, si realiza una consulta sobre el calendario sin permisos, el método devuelve un conjunto de datos vacíos.

Si instala una aplicación que utiliza el nuevo modelo de permisos en un dispositivo que no ejecuta la versión preliminar de Android M, el sistema la trata como cualquier otra aplicación: el sistema le pide al usuario, durante la instalación, que conceda los permisos declarados.

Nota: Para el lanzamiento de la versión preliminar, debe configurar la versión mínima del SDK en M Preview SDK para compilar con la versión del SDK preliminar. Esto significa que no podrá probar dichas aplicaciones en plataformas anteriores durante la versión preliminar para desarrolladores.

Permisos frente a intentos

En muchas situaciones, puede elegir entre dos formas para que sus aplicaciones realicen una tarea. Puede hacer que su aplicación solicite permiso para realizar la operación por sí misma. De lo contrario, puede hacer que la aplicación utilice un intento para que otra aplicación realice la tarea.

Por ejemplo, supongamos que su aplicación necesita poder tomar fotografías con la cámara del dispositivo. Su aplicación puede solicitar el permiso android.permission.CAMERA, lo que le permite a su aplicación acceder a la cámara directamente. Entonces, su aplicación utilizará las API de la cámara para controlar la cámara y tomar una fotografía. Este enfoque le otorga a su aplicación total control del proceso de fotografía y le permite incorporar la UI de la cámara en su aplicación.

Sin embargo, si no necesita dicho control, puede utilizar {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} para solicitar una imagen. Cuando ejecute el intento, se le solicita al usuario que elija una aplicación de cámara (en caso de que no haya una aplicación de cámara predeterminada) y esa aplicación tomará la fotografía. La aplicación de cámara devuelve la fotografía al método {@link android.app.Activity#onActivityResult onActivityResult()} de su aplicación.

De manera similar, si necesita realizar una llamada telefónica, acceder a los contactos del usuario, etc., lo puede hacer creando intentos apropiados o puede solicitar los permisos e ingresar directamente a los objetos apropiados. Cada enfoque tiene ventajas y desventajas.

Si utiliza los permisos:

Si utiliza un intento:

Codificación para permisos de tiempo de ejecución

Si su aplicación tiene como destino el nuevo M Developer Preview, deberá usar el nuevo modelo de permisos. Esto significa que, además de declarar los permisos necesarios en el manifiesto, también debe comprobar si tiene los permisos de tiempo de ejecución y solicitarlos en caso de no tenerlos.

Habilitar el nuevo modelo de permisos

Para habilitar el nuevo modelo de permisos de M Developer Preview, configure el atributo targetSdkVersion de la aplicación en "MNC" y compileSdkVersion en "android-MNC". Al hacerlo, se habilitan todas las características de los nuevos permisos.

Para el lanzamiento de la versión preliminar, debe establecer minSdkVersion en "MNC" para compilar con el SDK preliminar.

Establecer un permiso solo para la versión preliminar de Android M

Puede utilizar el nuevo elemento <uses-permission-sdk-m> en el manifiesto de la aplicación para indicar que se necesita un permiso solo para M Developer Preview. Si declara un permiso de esta manera, cuando la aplicación se instale en un dispositivo anterior, el sistema no le solicitará al usuario el permiso ni se lo otorgará a la aplicación. Al usar el elemento <uses-permission-sdk-m>, puede añadir nuevos permisos a las versiones actualizadas de su aplicación sin forzar a los usuarios a otorgar permisos cuando instalen la actualización.

Si la aplicación se ejecuta en un dispositivo con M Developer Preview, <uses-permission-sdk-m> se comporta al igual que <uses-permission>. El sistema no le solicita al usuario que otorgue ningún permiso al instalar la aplicación y la aplicación solicita los permisos a medida que se necesiten.

Solicitar permisos

Si su aplicación utiliza el nuevo modelo de permisos de M Developer Preview, no se le pedirá al usuario que otorgue todos los permisos cuando la aplicación se ejecute por primera vez en un dispositivo con la versión preliminar de Android M. En su lugar, su aplicación solicita los permisos a medida que los necesita. Cuando su aplicación solicita un permiso, el sistema le muestra un diálogo al usuario.

Si su aplicación se ejecuta en un dispositivo con SDK 22 o anterior, la aplicación utiliza el modelo de permisos anterior. Cuando el usuario instala la aplicación, se le solicita que otorgue todos los permisos que la aplicación requiere en su manifiesto, excepto aquellos permisos marcados con <uses-permission-sdk-m>.

Controlar en qué plataforma se ejecuta la aplicación

Este modelo de permisos es compatible solamente con dispositivos que ejecutan M Developer Preview. Antes de llamar a cualquiera de estos métodos, la aplicación debe verificar en qué plataforma se está ejecutando y, para hacerlo, se controla el valor de {@link android.os.Build.VERSION#CODENAME Build.VERSION.CODENAME}. Si el dispositivo ejecuta M Developer Preview, {@link android.os.Build.VERSION#CODENAME CODENAME} es "MNC".

Controlar si la aplicación cuenta con los permisos necesarios

Cuando el usuario intenta realizar algo que requiere un permiso, la aplicación controla si ya tiene el permiso para realizar esa operación. Para hacerlo, la aplicación llama a Context.checkSelfPermission( permission_name). La aplicación debe realizar este control incluso si sabe que el usuario ya ha concedido ese permiso, ya que el usuario puede revocar los permisos de una aplicación en cualquier momento. Por ejemplo, si un usuario quiere usar una aplicación para tomar una fotografía, la aplicación llama a Context.checkSelfPermission(Manifest.permission.CAMERA).

Tabla 1. Permisos y grupo de permisos.

Grupo de permisos Permisos
android.permission-group.CALENDAR
  • android.permission.READ_CALENDAR
  • android.permission.WRITE_CALENDAR
android.permission-group.CAMERA
  • android.permission.CAMERA
android.permission-group.CONTACTS
  • android.permission.READ_CONTACTS
  • android.permission.WRITE_CONTACTS
  • android.permission.READ_PROFILE
  • android.permission.WRITE_PROFILE
android.permission-group.LOCATION
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION
android.permission-group.MICROPHONE
  • android.permission.RECORD_AUDIO
android.permission-group.PHONE
  • android.permission.READ_PHONE_STATE
  • android.permission.CALL_PHONE
  • android.permission.READ_CALL_LOG
  • android.permission.WRITE_CALL_LOG
  • com.android.voicemail.permission.ADD_VOICEMAIL
  • android.permission.USE_SIP
  • android.permission.PROCESS_OUTGOING_CALLS
android.permission-group.SENSORS
  • android.permission.BODY_SENSORS
  • android.permission.USE_FINGERPRINT
android.permission-group.SMS
  • android.permission.SEND_SMS
  • android.permission.RECEIVE_SMS
  • android.permission.READ_SMS
  • android.permission.RECEIVE_WAP_PUSH
  • android.permission.RECEIVE_MMS
  • android.permission.READ_CELL_BROADCASTS

Solicitar permisos si se necesitan

Si la aplicación no posee los permisos que necesita, llama al método Activity.requestPermissions(String[], int) para solicitar el permiso o los permisos apropiados. La aplicación pasa el permiso o los permisos que necesita y un “código de solicitud” entero. Este método funciona de manera asincrónica: realiza la devolución inmediatamente y cuando el usuario responde a la ventana de diálogo, el sistema llama al método de devolución de llamada de la aplicación con los resultados, y pasa el mismo “código de solicitud” que pasó la aplicación a requestPermissions().

El siguiente código verifica si la aplicación tiene permisos para leer los contactos del usuario y solicita los permisos de ser necesario:

if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant

    return;
}

Administrar la respuesta a la solicitud de permisos

Cuando una aplicación solicita permisos, el sistema le muestra al usuario una ventana de diálogo. Cuando el usuario responde, el sistema invoca Activity.onRequestPermissionsResult(int, String[], int[]) de su aplicación y le transfiere la respuesta del usuario. Su aplicación necesita invalidar ese método. La devolución de llamada pasa el mismo código de solicitud que usted pasó a requestPermissions(). Por ejemplo, si una aplicación solicita acceso READ_CONTACTS, es posible que tenga el siguiente método de devolución de llamada:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! do the
                // calendar task you need to do.

            } else {

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

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

Si el usuario concede un permiso, el sistema le otorga a la aplicación todos los permisos enumerados en el manifiesto para esa área funcional. Se deben tomar acciones apropiadas si el usuario rechaza la solicitud. Por ejemplo, usted podría desactivar cualquier acción del menú que dependa de este permiso.

Cuando el sistema le solicita al usuario que otorgue un permiso, el usuario tiene la opción de indicarle al sistema que no solicite ese permiso de nuevo. En ese caso, cuando la aplicación utiliza requestPermissions() para solicitar ese permiso, el sistema rechaza la solicitud inmediatamente. En este caso, el sistema llama a su onRequestPermissionsResult() de la misma manera en que lo haría si el usuario hubiese rechazado explícitamente su solicitud nuevamente. Por esta razón, su aplicación no puede asumir que se ha llevado a cabo algún tipo de interacción con el usuario.

Prueba de permisos de tiempo de ejecución

Si su aplicación tiene como destino M Developer Preview, debe probar que administre los permisos correctamente. No debe asumir que su aplicación tiene algún permiso en particular cuando se ejecuta. Cuando la aplicación se ejecuta por primera vez, es muy probable que no tenga permisos y el usuario puede revocar o reestablecer los permisos en cualquier momento.

Debe probar su aplicación para asegurarse de que funciona correctamente en todas las situaciones de permisos. Con el SDK de la versión preliminar de Android M, hemos brindado nuevos comandos Android Debug Bridge (adb) que le permitirán probar su aplicación con cualquier configuración de permisos que necesite probar.

Nuevas opciones y comandos adb

Las herramientas de plataforma del SDK de la versión preliminar de Android M contienen varios comandos nuevos que le permiten probar la manera en que su aplicación administra los permisos.

Instalar con permisos

Puede utilizar la nueva opción -g del comando adb install, que instala la aplicación y concede todos los permisos enumerados en el manifiesto de la aplicación:

$ adb install -g <path_to_apk>

Conceder y revocar permisos

Puede utilizar los comandos ADB nuevos package manager (pm) para conceder y revocar permisos a una aplicación instalada. Esta funcionalidad puede resultar útil para pruebas automáticas.

Para conceder un permiso, utilice el comando grant de package manager:

$ adb pm grant <package_name> <permission_name>

Por ejemplo, para conceder el paquete de permisos com.example.myapp para grabar audio utilice este comando:

$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO

Para revocar un permiso, utilice el comando revoke de package manager:

$ adb pm revoke <package_name> <permission_name>

Mejores prácticas

El nuevo modelo de permisos brinda a los usuarios una experiencia más fluida y les facilita la instalación de aplicaciones, además de hacerlos sentir cómodos con las actividades de sus aplicaciones. Sugerimos las siguientes mejores prácticas para obtener el mayor beneficio del nuevo modelo.

Solicite solo los permisos que necesite

Cada vez que solicite un permiso, usted obliga al usuario a tomar una decisión. La funcionalidad de su aplicación se verá reducida si el usuario rechaza la solicitud. Debe minimizar la cantidad de veces que realiza estas solicitudes.

Por ejemplo, a menudo, su aplicación puede obtener la funcionalidad necesaria a través de un intento en lugar de una solicitud de permiso. Si su aplicación necesita tomar fotografías con la cámara del teléfono, la aplicación puede utilizar un intento {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE}. Cuando su aplicación ejecuta el intento, el sistema le solicita al usuario que elija una aplicación para la cámara que ya está instalada a fin de tomar la fotografía.

No abrume al usuario

Si expone al usuario a muchas solicitudes de permisos al mismo tiempo, lo abrumará y hará que deje de usar su aplicación. Por el contrario, debe pedir permisos en la medida que los necesite.

A veces, uno o más permisos pueden ser absolutamente necesarios para la aplicación. En ese caso, es recomendable pedir todos los permisos no bien se inicie la aplicación. Por ejemplo, si crea una aplicación de fotografía, la aplicación necesitará acceso a la cámara del dispositivo. Cuando el usuario inicie la aplicación por primera vez, no se sorprenderá si la aplicación le solicita permiso para usar la cámara. Sin embargo, si la misma aplicación además tuviese una característica para compartir fotografías con los contactos del usuario, no solicite ese permiso la primera vez que se ejecute. En su lugar, espere hasta que el usuario utilice la característica “compartir” para solicitar el permiso en ese momento.

Si su aplicación proporciona un tutorial, se recomienda que se pidan los permisos esenciales de la aplicación al final del tutorial.

Explique por qué se necesitan los permisos

El diálogo de permisos que muestra el sistema cuando llama a requestPermissions() informa qué permisos necesita su aplicación pero no establece el motivo. A veces, el usuario puede confundirse. Es una buena idea explicarle al usuario los motivos por los que la aplicación necesita esos permisos antes de llamar a requestPermissions().

Por ejemplo, una aplicación de fotografía puede solicitar servicios de ubicación para añadir una etiqueta geográfica a las fotografías. Es posible que un usuario típico no sepa que una fotografía puede contener información sobre la ubicación y se confundiría si una aplicación de fotografía solicita la ubicación. En este caso, es recomendable que la aplicación le informe al usuario acerca de esta característica antes de llamar a requestPermissions().

Una forma de hacerlo es incorporar estas solicitudes en el tutorial de la aplicación. El tutorial puede mostrar todas las características de la aplicación, una por vez, y mientras lo hace explicar los permisos que son necesarios. Por ejemplo, el tutorial de la aplicación de fotografía puede mostrar la característica “compartir fotografías con contactos” y luego explicarle al usuario que debe otorgar permisos para que la aplicación vea los contactos del usuario. La aplicación puede entonces llamar a requestPermissions() para solicitarle al usuario ese acceso. Por supuesto, no todos los usuarios siguen el tutorial, por lo que aun así debe controlar y solicitar los permisos durante el funcionamiento normal de la aplicación.