Cómo solicitar permisos de la app

Cada app para Android se ejecuta en una zona de pruebas con acceso limitado. Si la app necesita usar recursos o información ajenos a su propia zona de pruebas, puedes declarar un permiso y configurar una solicitud de permiso que proporcione este acceso. Estos pasos forman parte del flujo de trabajo para usar permisos.

Si declaras algún permiso riesgoso y, si tu app está instalada en un dispositivo con Android 6.0 (nivel de API 23) o una versión posterior, debes seguir los pasos de esta guía a fin de solicitar los permisos riesgosos durante el tiempo de ejecución.

Si no declaras ningún permiso riesgoso o si tu app se instala en un dispositivo con Android 5.1 (nivel de API 22) o una versión anterior, los permisos se otorgan de manera automática y no necesitas completar los demás pasos de esta página.

Principios básicos

Los principios básicos para solicitar permisos durante el tiempo de ejecución son los siguientes:

  • Solicita permisos en contexto cuando el usuario comience a interactuar con la función que lo requiere.
  • No bloquees al usuario. Proporciona siempre la opción de cancelar un flujo de IU educativo relacionado con los permisos.
  • Si el usuario rechaza o revoca un permiso que necesita una función, debes realizar una degradación elegante de tu app para que pueda seguir usándola; para ello, puedes inhabilitar la función que requiere el permiso.
  • No des por sentado ningún comportamiento del sistema. Por ejemplo, no supongas que todos los permisos aparecen en el mismo grupo de permisos. Esos grupos simplemente ayudan al sistema a minimizar la cantidad de diálogos que se presentan al usuario cuando una app solicita permisos relacionados entre sí.

Flujo de trabajo para solicitar permisos

Antes de declarar y solicitar permisos de tiempo de ejecución en tu app, evalúa si es necesario. Puedes completar muchos casos de uso en la app, como tomar fotos, pausar la reproducción de contenido multimedia y mostrar anuncios relevantes, sin declarar ningún permiso.

Si concluyes que la app necesita declarar y solicitar permisos de tiempo de ejecución, completa estos pasos:

  1. En el archivo de manifiesto de la app, declara los permisos que podría necesitar.
  2. Diseña la UX de tu app para que se asocien determinadas acciones con permisos de tiempo de ejecución específicos. Los usuarios deberían saber qué acciones pueden requerir la habilitación de un permiso para que la app acceda a sus datos privados.
  3. Espera a que el usuario invoque la tarea o acción de la app que requiere acceso a datos privados específicos. En ese momento, la app puede solicitar el permiso de tiempo de ejecución necesario para acceder a esos datos.
  4. Verifica si el usuario ya otorgó el permiso de tiempo de ejecución que requiere la app. De ser así, esta ya puede acceder a los datos privados del usuario. De lo contrario, continúa con el paso siguiente.

    Deberás comprobar si tienes ese permiso cada vez que realices una operación que lo requiera.

  5. Verifica si tu app debería mostrarle una justificación al usuario en la que se explique por qué la app necesita ese permiso durante el tiempo de ejecución. Si el sistema determina que no es necesario otorgar una justificación, continúa directamente con el siguiente paso, sin mostrar un elemento de la IU.

    En cambio, si el sistema determina que se debe proporcionar, muestra la justificación al usuario en un elemento de la IU. En ella, se debe explicar claramente a qué datos intenta acceder la app y qué beneficios puede proporcionarle al usuario si este otorga el permiso de tiempo de ejecución. Después de que el usuario acepte la justificación, continúa con el siguiente paso.

  6. Solicita el permiso de tiempo de ejecución que requiere tu app para poder acceder a los datos privados del usuario. El sistema muestra un mensaje de permiso de tiempo de ejecución, como el que se muestra en la página de resumen de permisos.

  7. Verifica la respuesta del usuario, si eligió otorgar o denegar el permiso de tiempo de ejecución.

  8. Si el usuario otorgó el permiso a tu app, esta podrá acceder a sus datos privados. En cambio, si el usuario rechazó el permiso, deberás reducir la experiencia en la app de forma elegante para que siga proporcionando funcionalidad, incluso sin la información protegida por ese permiso.

En la figura 1, se ilustran el flujo de trabajo y el conjunto de decisiones asociados con este proceso:

Figura 1: Diagrama en el que se muestra el flujo de trabajo para declarar y solicitar permisos de tiempo de ejecución en Android

Determina si tu app ya recibió el permiso

Para verificar si el usuario ya otorgó un permiso en particular a tu app, pasa ese permiso al método ContextCompat.checkSelfPermission(). Este método muestra PERMISSION_GRANTED o PERMISSION_DENIED, según si tu app tiene el permiso o no.

Explica el motivo por el que la app necesita el permiso

En el diálogo de permisos que muestra el sistema cuando llamas a requestPermissions(), se indican los permisos que necesita tu app, pero no el motivo. A veces, esto puede confundir al usuario. Se recomienda explicarle los motivos por los cuales tu app necesita esos permisos antes de que llames a requestPermissions().

Algunas investigaciones muestran que los usuarios se sienten más cómodos con las solicitudes de permisos si saben para qué los necesita la app. Un estudio de usuarios mostró lo siguiente:

La disposición de un usuario para otorgar permiso a una app determinada se ve notablemente afectada por el propósito asociado con el permiso. Por ejemplo, la disposición de un usuario de otorgar acceso a su ubicación variará en función de si la solicitud se realiza para respaldar la funcionalidad central de la app o compartir esa información con una red de publicidad o una empresa de análisis de datos.1

Luego de colaborar con otras personas en relación con este tema, el profesor Jason Hong, de la CMU, concluyó que generalmente:

cuando las personas saben por qué una app usa información sensible, como su ubicación (por ejemplo, para publicidad orientada), se sienten más cómodas que cuando no se les da una explicación.1

En consecuencia, si solo usas una fracción de las llamadas de la API que pertenecen a un grupo de permisos, te será más fácil indicar explícitamente los permisos que usas y por qué. Por ejemplo:

  • Si solo usas la ubicación aproximada, infórmalo al usuario en la descripción de tu app o los artículos de ayuda.
  • Si necesitas acceso a mensajes SMS para recibir códigos de autenticación que protegen al usuario contra fraudes, infórmaselo en la descripción de tu app o la primera vez que tu app acceda a los datos.

    Nota: Si tu app se orienta a dispositivos que ejecutan Android 8.0 (nivel de API 26) o una versión posterior, no solicites el permiso READ_SMS como parte de la verificación de las credenciales del usuario. En su lugar, genera un token específico de la app con createAppSpecificSmsToken() y, luego, pásalo a otra app o servicio que pueda enviar un mensaje de verificación por SMS.

En ciertos casos, se recomienda informar a los usuarios respecto del acceso a datos sensibles en tiempo real. Por ejemplo, si accedes a la cámara o al micrófono, se recomienda que se lo informes al usuario con un ícono de notificación en algún sector de tu app, o en la bandeja de notificaciones (si la app se ejecuta en segundo plano), de manera que no parezca que recopilas datos de forma clandestina.

Por último, si tienes que solicitar un permiso para realizar alguna tarea en tu app, pero el motivo no está claro para el usuario, busca una manera de informarle por qué necesitas los permisos más sensibles.

Si el método ContextCompat.checkSelfPermission() muestra PERMISSION_DENIED, llama a shouldShowRequestPermissionRationale(). Si este método muestra true, enseña una IU educativa al usuario. En esta IU, describe por qué la función que el usuario quiere habilitar necesita un permiso en particular.

Además, si tu app solicita un permiso relacionado con la ubicación, el micrófono o la cámara, procura explicar por qué tu app necesita acceso a esa información.

Cómo solicitar permisos

Después de que el usuario vea una IU educativa, o de que el valor que muestra shouldShowRequestPermissionRationale() indique que esta vez no necesitas mostrar una IU educativa, solicita el permiso. Los usuarios ven un diálogo de permisos del sistema en el que pueden elegir si desean otorgar un permiso en particular a tu app.

Por lo general, administras un código de solicitud como parte de la solicitud de permiso y lo incluyes en tu lógica de devolución de llamada de permiso. Otra opción es usar el contrato RequestPermission, que se incluye en una biblioteca de AndroidX, en el que permites que el sistema administre el código de solicitud de permiso por ti. Debido a que usar el contrato RequestPermission simplifica tu lógica, se recomienda que lo uses siempre que sea posible.

Permite que el sistema administre el código de solicitud de permiso

Para permitir que el sistema administre el código de solicitud asociado a una solicitud de permisos, agrega una dependencia en la siguiente biblioteca del archivo build.gradle de tu módulo.

Luego puedes usar una de las siguientes clases:

En los siguientes pasos, se muestra cómo usar el contrato RequestPermission. El proceso es casi el mismo para el contrato RequestMultiplePermissions.

  1. En la lógica de inicialización de tu actividad o fragmento, pasa una implementación de ActivityResultCallback a una llamada a registerForActivityResult(). La interfaz ActivityResultCallback define el modo en el que tu app controla la respuesta del usuario a la solicitud de permiso.

    Mantén una referencia al valor que muestra registerForActivityResult(), que es del tipo ActivityResultLauncher.

  2. Para mostrar el diálogo de permisos del sistema cuando sea necesario, llama al método launch() en la instancia de ActivityResultLauncher que guardaste en el paso anterior.

    Después de llamar a launch(), aparecerá el diálogo de permisos del sistema. Cuando el usuario toma una decisión, el sistema invoca de forma asíncrona tu implementación de ActivityResultCallback, que definiste en el paso anterior.

    Nota: Tu app no puede personalizar el diálogo que aparece cuando llamas a launch(). Si deseas proporcionar más información o contexto al usuario, cambia la IU de tu app a fin de que sea más fácil para los usuarios comprender por qué una función necesita un permiso en particular. Por ejemplo, puedes cambiar el texto del botón que habilita la función.

    Además, el texto del diálogo de permisos del sistema hace referencia al grupo de permisos asociado con el permiso que solicitaste. Esta forma de agrupar permisos está diseñada para la facilidad de uso del sistema, y tu app no debería depender de los permisos dentro o fuera de un grupo de permisos específico.

En el siguiente fragmento de código, se muestra cómo controlar la respuesta de permisos:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // features requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });

Y en este fragmento de código, se muestra el proceso recomendado para verificar un permiso y solicitar un permiso al usuario cuando sea necesario:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

Administra por tu cuenta el código de solicitud de permiso

En lugar de permitir que el sistema administre el código de solicitud de permiso, puedes administrarlo por tu cuenta como alternativa. Para hacerlo, incluye el código de solicitud en una llamada a requestPermissions().

En el siguiente fragmento de código, se muestra cómo solicitar un permiso con un código de solicitud:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.REQUESTED_PERMISSION),
                REQUEST_CODE)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.REQUESTED_PERMISSION },
            REQUEST_CODE);
}

Una vez que el usuario responde al diálogo de permisos del sistema, este invoca la implementación de onRequestPermissionsResult() de tu app. El sistema pasa la respuesta del usuario al diálogo de permisos, así como el código de solicitud que definiste, como se muestra en el siguiente fragmento de código:

Kotlin

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            }  else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

Solicita varios permisos

Cuando solicites permisos de ubicación, sigue las mismas prácticas recomendadas para cualquier otro permiso de tiempo de ejecución. Una diferencia importante cuando se trata de permisos de ubicación es que el sistema incluye varios permisos relacionados con la ubicación. Los permisos que solicites y el modo en que los solicites dependerán de los requisitos de ubicación del caso de uso de tu app.

Ubicación en primer plano

Si tu app contiene una función que comparte o recibe información de ubicación solo una vez o durante un tiempo definido, esa función requiere acceso a la ubicación en primer plano. Estos son algunos ejemplos:

  • Dentro de una app de navegación, una función permite a los usuarios obtener instrucciones paso a paso.
  • Dentro de una app de mensajería, una función permite a los usuarios compartir su ubicación actual con otro usuario.

El sistema considera que tu app usa la ubicación en primer plano si una función accede a la ubicación actual del dispositivo en una de las siguientes situaciones:

  • Una actividad que pertenece a tu app es visible.
  • Tu app ejecuta un servicio en primer plano. Cuando se ejecuta un servicio en primer plano, el sistema muestra una notificación persistente para atraer la atención del usuario. Tu app conserva el acceso cuando se coloca en segundo plano, por ejemplo, cuando el usuario presiona el botón Inicio en su dispositivo o apaga la pantalla.

    Además, se recomienda que declares un tipo de servicio en primer plano de location, como se muestra en el siguiente fragmento de código. En Android 10 (nivel de API 29) y versiones posteriores, debes declarar este tipo de servicio en primer plano.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements would go here. -->
    </service>
    

Declaras la necesidad de una ubicación en primer plano cuando tu app solicita los permisos ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION, como se muestra en el siguiente fragmento:

<manifest ... >
  <!-- Always include this permission -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Ubicación en segundo plano

Una app requiere acceso a la ubicación en segundo plano si una función dentro de la app comparte constantemente la ubicación con otros usuarios o usa la API de geovallado. Entre los ejemplos, se incluyen los siguientes:

  • Dentro de una app familiar para compartir la ubicación, una función permite que los usuarios compartan la ubicación de forma continua con los miembros de la familia.
  • Dentro de una app de IoT, una función permite al usuario configurar sus dispositivos para la casa de modo que se apaguen cuando el usuario salga de su casa y se vuelvan a activar cuando regrese.

El sistema considera que tu app usa la ubicación en segundo plano si accede a la ubicación actual del dispositivo en una situación diferente de la descrita en la sección Ubicación en primer plano. La precisión de la ubicación en segundo plano es la misma que la precisión de la ubicación en primer plano, que depende de los permisos de ubicación que declare tu app.

En Android 10 (nivel de API 29) y versiones posteriores, debes declarar el permiso ACCESS_BACKGROUND_LOCATION en el manifiesto de tu app para solicitar acceso a la ubicación en segundo plano durante el tiempo de ejecución. En las versiones anteriores de Android, cuando tu app recibe acceso a la ubicación en primer plano, también recibe automáticamente acceso a la ubicación en segundo plano.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

Controla la denegación de permisos

Si el usuario rechaza una solicitud de permiso, tu app debe ayudar a los usuarios a comprender las implicaciones de esta denegación. En particular, tu app debe informar a los usuarios sobre las funciones que no se pueden usar debido a la falta de permiso. Cuando lo hagas, ten en cuenta las siguientes recomendaciones:

  • Orienta la atención del usuario. Destaca una parte específica de la IU de tu app en la que la funcionalidad sea limitada porque no tiene los permisos necesarios. Estos son algunos ejemplos de lo que puedes hacer:

    • Muestra un mensaje en el que habrían aparecido los resultados o los datos de la función.
    • Muestra un botón diferente que contenga un ícono y un color de error.
  • Brinda información específica. No muestres un mensaje genérico; en su lugar, menciona qué funciones no están disponibles porque tu app no tiene el permiso necesario.

  • No bloquees la interfaz de usuario. En otras palabras, no muestres un mensaje de advertencia de pantalla completa que impida a los usuarios seguir usando tu app.

Sugerencia: Tu app debe fomentar la mejor experiencia del usuario posible, incluso después de que se deniegue el permiso. Por ejemplo, si se deniega el acceso al micrófono, aún debes promover la usabilidad completa de la funcionalidad del texto.

Al mismo tiempo, la app debe respetar la decisión del usuario de denegar un permiso. A partir de Android 11 (nivel de API 30), si el usuario presiona Rechazar para un permiso específico más de una vez durante la instalación de la app en un dispositivo, no verá el diálogo de permisos del sistema si tu app solicita ese permiso nuevamente. La acción del usuario implica "no volver a preguntar". En versiones anteriores, los usuarios veían el diálogo de permisos del sistema cada vez que tu app solicitaba un permiso a menos que el usuario hubiera seleccionado una opción o casilla de verificación de "no volver a preguntar".

Si un usuario deniega una solicitud de permiso más de una vez, se considerará una denegación permanente. Es muy importante solicitarles permisos a los usuarios solo cuando necesitan acceso a una función específica; de lo contrario, podrías perder, de forma inadvertida, la capacidad de volver a solicitar permisos.

En algunas situaciones, se puede denegar automáticamente el permiso, sin que el usuario realice ninguna acción (de manera similar, también se puede otorgar automáticamente un permiso). Es importante no dar nada por sentado sobre el comportamiento automático. Cada vez que tu app necesite acceder a una función que requiera un permiso, deberás verificar que se le otorgue ese permiso.

Para proporcionar la mejor experiencia del usuario cuando solicitas permisos para una app, también puedes consultar las Prácticas recomendadas para solicitar permisos de apps.

Permisos únicos

La opción &quot;Solo esta vez&quot; es el segundo de los tres botones en la pantalla de diálogo.
Figura 2: Diálogo del sistema que aparece cuando una app solicita un permiso único

A partir de Android 11 (nivel de API 30), cada vez que tu app solicita un permiso relacionado con la ubicación, el micrófono o la cámara, el diálogo de permisos para el usuario contiene una opción llamada Solo esta vez, como la que se muestra en la figura 2. Si el usuario selecciona esta opción, se otorgará un permiso único temporal a la app.

Luego la app podrá acceder a los datos relacionados durante un período que dependerá del comportamiento de tu app y de las acciones del usuario:

  • Mientras su actividad sea visible, la app podrá acceder a los datos.
  • Si el usuario envía la app a segundo plano, esta podrá seguir accediendo a los datos durante un breve período.
  • Si inicias un servicio en primer plano mientras la actividad está visible y el usuario lleva la app a segundo plano, esta puede continuar accediendo a los datos hasta que se detenga ese servicio.
  • Si el usuario revoca el permiso único (por ejemplo, en la configuración del sistema), la app no podrá acceder a los datos, independientemente de si iniciaste un servicio en primer plano. Al igual que con cualquier otro permiso, si el usuario revoca el permiso único de la app, finalizará el proceso.

La próxima vez que el usuario abra tu app y una función requiera acceso a la ubicación, el micrófono o la cámara, se le solicitará nuevamente el permiso.

Android restablece automáticamente los permisos de las apps que no se usan

Si tu app se orienta a Android 11 (nivel de API 30) o versiones posteriores, y no se usa durante algunos meses, el sistema restablece automáticamente los permisos de tiempo de ejecución sensibles que el usuario le otorgó a tu app. Obtén más información en la guía sobre la hibernación de la app.

Solicita convertirte en el controlador predeterminado si es necesario

Algunas apps dependen del acceso a la información sensible del usuario que se relaciona con sus registros de llamadas y mensajes SMS. Si quieres solicitar los permisos específicos para registros de llamadas y mensajes SMS, y publicar tu app en Play Store, debes solicitar al usuario que configure tu app como controlador predeterminado para una función principal del sistema antes de solicitar estos permisos de tiempo de ejecución.

Para obtener más información sobre los controladores predeterminados, así como orientación sobre cómo mostrar una solicitud de estos a los usuarios, consulta la guía sobre permisos que se usan solo en controladores predeterminados.

Otorga todos los permisos de tiempo de ejecución con fines de prueba

Para otorgar todos los permisos de tiempo de ejecución automáticamente cuando instalas una app en un emulador o dispositivo de prueba, usa la opción -g para el comando adb shell install, como se muestra en el siguiente fragmento de código:

adb shell install -g PATH_TO_APK_FILE

Recursos adicionales

Para obtener información adicional sobre permisos, consulta los siguientes artículos:

Para descubrir cómo solicitar permisos, descarga las siguientes apps de ejemplo:

  • Ejemplo de RuntimePermissionsBasic de Android Java | Kotlin