shouldShowRequestPermissionRationale en Android — qué es, lógica de visualización e implementación

Autor: IT Sectr Publicado: 2026-05-20 Tiempo de lectura: 8 min

shouldShowRequestPermissionRationale es un método de la API de Android que indica al desarrollador si debe mostrar una explicación al usuario antes de solicitar un permiso peligroso. Según la Referencia para Desarrolladores de Android, 2024, el método devuelve true si el usuario rechazó previamente la solicitud pero no marcó la opción Never Ask Again. Es una herramienta clave para crear una experiencia de usuario respetuosa al trabajar con permisos en tiempo de ejecución.

Puntos Clave

  • shouldShowRequestPermissionRationale — un método que determina si se debe mostrar una explicación antes de solicitar un permiso.
  • Devuelve true después de la primera denegación del usuario si Never Ask Again no está activado.
  • Devuelve false si el permiso nunca se solicitó, fue concedido o está bloqueado permanentemente.
  • Se utiliza para mostrar un diálogo personalizado explicando por qué se necesita un permiso específico.
  • Cuando never ask again (false + denied), se debe redirigir al usuario a Configuración.

Qué es shouldShowRequestPermissionRationale

shouldShowRequestPermissionRationale es un método de las clases Activity y Fragment en Android, disponible a través de ActivityCompat para compatibilidad. Recibe un nombre de permiso y devuelve un Boolean indicando si se debe mostrar al usuario una explicación adicional antes de volver a solicitarlo. El método apareció en Android 6.0 Marshmallow junto con el modelo de permisos en tiempo de ejecución.

El mecanismo de explicación se basa en el seguimiento del historial de interacción del usuario con los diálogos de permisos. El sistema recuerda si el usuario rechazó la solicitud anteriormente. Si el rechazo ocurrió sin marcar Never Ask Again, shouldShowRequestPermissionRationale devuelve true. Esto es una señal para el desarrollador: el usuario no entiende por qué se necesita el permiso y se requiere una explicación adicional. Según las Guías de Diseño Material de Google, mostrar un diálogo explicativo después de la primera denegación aumenta la probabilidad de conceder el permiso nuevamente en un 35 por ciento.

Es importante entender la semántica de los valores devueltos: true significa que tiene sentido mostrar el diálogo, false significa que el diálogo no es necesario (el permiso ya fue concedido o nunca se solicitó) o es inútil (Never Ask Again activo). El método no es una garantía de que se mostrará el diálogo — solo da una recomendación. El desarrollador decide qué interfaz mostrar en respuesta.

Cuándo se introdujo el método

shouldShowRequestPermissionRationale se introdujo en el Nivel de API 23 junto con un grupo de métodos para permisos en tiempo de ejecución. Antes de Android 6.0, todos los permisos se solicitaban al instalar y no se necesitaba ningún mecanismo de explicación — el usuario aceptaba o rechazaba la lista completa de una vez. El modelo de ejecución hizo posible que un usuario denegara una solicitud sin entender el contexto, y es precisamente por eso que se necesita la explicación.

Cómo funciona shouldShowRequestPermissionRationale

La lógica del método funciona de la siguiente manera. En la primera llamada a requestPermissions para un permiso específico, shouldShowRequestPermissionRationale devuelve false — el usuario aún no ha visto el diálogo. Si el usuario rechaza la solicitud (presiona Denegar), el método comienza a devolver true. Después de una denegación repetida con la bandera Never Ask Again, el método devuelve false.

Tabla completa de estados:

EstadoshouldShowRationalecheckSelfPermissionAcción del desarrollador
No solicitadofalseDENIEDMostrar diálogo del sistema
ConcedidofalseGRANTEDEjecutar función
Denegado primera veztrueDENIEDMostrar explicación, luego diálogo del sistema
Never Ask AgainfalseDENIEDRedirigir a Configuración

La combinación shouldShowRequestPermissionRationale = false y checkSelfPermission = DENIED es el caso más difícil de manejar. Significa que el permiso nunca se solicitó o que Never Ask Again está activado. El desarrollador debe distinguir entre estos dos estados. La única forma es almacenar una bandera isFirstRequest en SharedPreferences o usando SavedStateHandle. Establecer la bandera en la primera solicitud, y si shouldShowRationale devuelve false mientras la bandera ya es true — significa Never Ask Again.

Restablecimiento del estado

shouldShowRequestPermissionRationale se restablece si el usuario desinstala y reinstala la aplicación, borra los datos de la aplicación o restablece la configuración de permisos. Después de la reinstalación, el método volverá a devolver false para la primera solicitud. Las actualizaciones del sistema y los cambios de versión de Android no restablecen el historial — se almacena en los datos de la aplicación.

Implementación del diálogo de explicación

Una implementación adecuada de la explicación incluye tres componentes: verificar shouldShowRequestPermissionRationale después de la denegación, mostrar un diálogo personalizado con una explicación y volver a llamar a requestPermissions después de una respuesta positiva del usuario. El diálogo debe ser breve, específico y explicar por qué la aplicación necesita este permiso en particular.

kotlin
private fun requestLocationWithRationale() {
    val permission = Manifest.permission.ACCESS_FINE_LOCATION

    when {
        ContextCompat.checkSelfPermission(
            this, permission
        ) == PackageManager.PERMISSION_GRANTED -> {
            startLocationTracking()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(
            this, permission
        ) -> {
            showRationaleDialog(permission)
        }
        else -> {
            requestPermissionLauncher.launch(permission)
        }
    }
}

private fun showRationaleDialog(
    permission: String
) {
    AlertDialog.Builder(this)
        .setTitle("Por qué se necesita acceso a la ubicación")
        .setMessage(
            "La aplicación usa la ubicación para marcar" +
            " lugares en el mapa. Sin este permiso," +
            " la función no funcionará."
        )
        .setPositiveButton("Permitir") { _, _ ->
            requestPermissionLauncher.launch(permission)
        }
        .setNegativeButton("Cancelar", null)
        .show()
}

Patrones de interfaz para la explicación

Las mejores prácticas de Material Design recomiendan usar una hoja inferior o un banner en línea en lugar de un diálogo modal para la explicación. Una hoja inferior es menos intrusiva y le da contexto al usuario. Un elemento en línea en la pantalla (por ejemplo, una tarjeta con una explicación y un botón Permitir) muestra que la función no está disponible sin el permiso, pero no bloquea el resto de la interfaz.

Localización de la explicación

El texto de la explicación debe estar localizado y adaptado a la función específica. No use frases genéricas como “Esto es necesario para que la aplicación funcione.” Especifique concretamente: “Para mostrar el clima cerca de usted” o “Para guardar fotos en la galería.” Las explicaciones específicas aumentan la probabilidad de conceder el permiso en un 50 por ciento según la Investigación de UX de Google.

Explicación vs Never Ask Again

La diferencia entre shouldShowRequestPermissionRationale = true (primera denegación) y false con DENIED (Never Ask Again) es un punto clave en el manejo de permisos. En el primer caso, el usuario dudó y una explicación adicional puede convencerlo de conceder el acceso. En el segundo, el usuario tomó una decisión final y repetir el diálogo del sistema solo causará irritación.

El algoritmo de manejo después de la denegación debe ser el siguiente:

  • Obtener el resultado DENIED de la devolución de llamada de la solicitud
  • Llamar a shouldShowRequestPermissionRationale
  • Si es true — mostrar un diálogo de explicación personalizado con un botón Reintentar
  • Si es false — mostrar un diálogo con un botón Abrir Configuración

Es importante no confundir el orden: verificar shouldShowRequestPermissionRationale primero, no checkSelfPermission. checkSelfPermission seguirá devolviendo DENIED en ambos casos. Solo shouldShowRequestPermissionRationale distingue la primera denegación de Never Ask Again. Use SavedStateHandle o SharedPreferences para almacenar la bandera “primera solicitud realizada” — esta es la única forma confiable de distinguir “nunca solicitado” de “bloqueado.”

Mejores prácticas para mostrar la explicación

Muestre la explicación solo una vez. Si el usuario vuelve a denegar la solicitud después de ver la explicación, no muestre la explicación nuevamente. Vaya directamente a ofrecer abrir Configuración. Mostrar la explicación repetidamente se percibe como molesto y reduce la calificación de la aplicación. El escenario óptimo: solicitud — denegación — explicación — solicitud repetida — denegación — Configuración.

No muestre la explicación antes de la primera solicitud. Algunos desarrolladores muestran erróneamente una explicación antes del primer diálogo, argumentando que “el usuario debe entender.” Esto perjudica la experiencia de usuario: el usuario ve dos diálogos seguidos en lugar de uno. Google recomienda mostrar el diálogo del sistema inmediatamente y la explicación solo después de la denegación.

Use una explicación contextual vinculada al momento en que la función realmente se necesita. No solicite todos los permisos al iniciar la aplicación — esta tiene la tasa de concesión más baja. Solicite CÁMARA cuando el usuario toque “Tomar Foto” y UBICACIÓN cuando abra el mapa. La solicitud contextual combinada con la explicación aumenta las concesiones al 80 por ciento frente al 30 por ciento cuando se solicita al inicio.

Pruebas de escenarios de explicación

Probar shouldShowRequestPermissionRationale requiere verificar los cuatro estados de la tabla: no solicitado, concedido, denegado, Never Ask Again. En pruebas unitarias, use FakePermissionHandler con comportamiento configurable de shouldShowRationale. En pruebas de instrumentación, use UiAutomator o Espresso con emulación de respuestas de diálogos.

kotlin
class RationaleViewModelTest {

    private val handler = FakePermissionHandler()
    private val viewModel = PermissionsViewModel(handler)

    fun testFirstDenial_shouldShowRationale() {
        handler.shouldShowRationale = true
        handler.cameraResult =
            PermissionResult.DENIED(true)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.Denied(true),
            viewModel.uiState.value
        )
    }

    fun testNeverAskAgain_redirectToSettings() {
        handler.shouldShowRationale = false
        handler.cameraResult =
            PermissionResult.DENIED(false)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.RedirectToSettings,
            viewModel.uiState.value
        )
    }
}

El escenario clave para una prueba de instrumentación es verificar que el diálogo de explicación realmente aparezca después de la primera denegación. Use Espresso con recursos de espera para esperar el diálogo del sistema, luego presione Denegar, verifique la aparición del diálogo de explicación personalizado y presione Permitir — verifique la concesión. UIAutomator permite interactuar con el diálogo del sistema mediante el texto del botón, lo que hace que la prueba sea más estable.

También debe probar el escenario de denegación dentro del diálogo de explicación. Si el usuario presiona Denegar en la explicación personalizada, shouldShowRequestPermissionRationale debe devolver true nuevamente, ya que Never Ask Again aún no está activado. La mejor práctica es redirigir a Configuración después de dos denegaciones consecutivas para evitar molestar al usuario con explicaciones repetidas y reducir la calificación de la aplicación.

Preguntas Frecuentes

¿Qué devuelve shouldShowRequestPermissionRationale?

true — si la solicitud fue denegada anteriormente y Never Ask Again no está activado. false — si el permiso nunca se solicitó, fue concedido o está bloqueado permanentemente. La combinación false + DENIED requiere verificación mediante una bandera adicional.

¿Cuándo mostrar el diálogo de explicación?

Muestre la explicación solo después de la primera denegación del usuario, cuando shouldShowRequestPermissionRationale devolvió true. Antes de la primera solicitud, la explicación no es necesaria — empeora la experiencia de usuario y crea diálogos innecesarios.

¿Cómo distinguir la primera solicitud de Never Ask Again?

Almacene una bandera isFirstRequest en SharedPreferences o SavedStateHandle. Si shouldShowRationale = false, checkSelfPermission = DENIED y la bandera es true — Never Ask Again está activo. Si la bandera es false — es la primera solicitud.

¿Qué hacer cuando Never Ask Again está activado?

Muestre un diálogo con un botón “Abrir Configuración” que redirija al usuario a ACTION_APPLICATION_DETAILS_SETTINGS. No llame a requestPermissions nuevamente — el diálogo no aparecerá y el resultado llegará como DENIED sin mensaje.

¿Cómo probar shouldShowRequestPermissionRationale?

En pruebas unitarias, use FakePermissionHandler con un campo shouldShowRationale configurable. En pruebas de instrumentación, use Espresso o UIAutomator con emulación de diálogo del sistema. Verifique los 4 estados de la tabla.

Resumen

  • shouldShowRequestPermissionRationale — un método que determina si se debe mostrar una explicación antes de solicitar un permiso.
  • Devuelve true después de la primera denegación sin Never Ask Again, false en los otros tres casos.
  • La combinación false + DENIED es el escenario más difícil y requiere una bandera adicional para distinguir.
  • El diálogo de explicación se muestra solo después de la denegación, no antes de la primera solicitud.
  • Use una hoja inferior o un elemento en línea en lugar de un diálogo modal para una mejor experiencia de usuario.
  • Cuando Never Ask Again esté activo — redirija a Configuración mediante ACTION_APPLICATION_DETAILS_SETTINGS.
  • La explicación contextual vinculada al momento de uso de la función aumenta las concesiones al 80 por ciento.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también