AndroidManifest Permissions: Conceptos clave, declaración y tipos de permisos

Autor: IT Sectr Publicado: 2026-05-21 Tiempo de lectura: 10 min

AndroidManifest Permissions son declaraciones de permisos en el archivo AndroidManifest.xml que determinan a qué recursos del sistema y datos tiene acceso una aplicación. Android requiere que cada permiso se declare en el manifiesto antes de usar la API correspondiente: desde la cámara y la geolocalización hasta el envío de SMS y el acceso a contactos. Según la Documentación para desarrolladores de Android, cada permiso pertenece a uno de cuatro niveles de protección: normal, dangerous, signature y special.

Puntos clave

  • AndroidManifest.xml — archivo de manifiesto con la declaración de todos los permisos de la aplicación
  • Niveles de protección — normal, dangerous, signature, special con diferentes mecanismos de solicitud
  • Runtime Permission — los permisos dangerous requieren solicitud en tiempo de ejecución (Android 6+)
  • Declarar vs Solicitar — la declaración en el manifiesto es obligatoria, pero los dangerous requieren una solicitud adicional en el código
  • Grupos — los permisos se agrupan; el consentimiento a uno concede acceso a todo el grupo

¿Qué son AndroidManifest Permissions?

AndroidManifest Permissions es el mecanismo de seguridad de Android que controla el acceso de las aplicaciones a datos protegidos y funciones del sistema. Cada aplicación debe declarar los permisos necesarios en el archivo AndroidManifest.xml mediante el elemento . Sin la declaración, la llamada a la API correspondiente generará un error de seguridad SecurityException.

El modelo de permisos de Android ha pasado por varias etapas de evolución. Antes de Android 6.0 (API 23), todos los permisos se concedían en la instalación: el usuario veía la lista completa y aceptaba o rechazaba la instalación de la aplicación. A partir de Android 6.0, los permisos de nivel dangerous se solicitan en tiempo de ejecución (Runtime Permissions), lo que da al usuario un control más flexible.

Los permisos se dividen en cuatro niveles de protección: normal (se conceden automáticamente al instalar), dangerous (requieren solicitud en tiempo de ejecución), signature (solo disponibles para aplicaciones firmadas con el mismo certificado) y special (requieren activación por separado en los ajustes). Cada nivel tiene su propio mecanismo de concesión y revocación.

Según Google I/O 2024, Android 15 planea introducir permisos más granulares: el usuario podrá conceder acceso solo a archivos específicos en la biblioteca multimedia, no a toda la colección. Esto continúa la tendencia de Android a minimizar la cantidad de datos proporcionados por defecto.

Diferencia con el modelo de permisos de iOS

A diferencia de iOS, donde todos los permisos se solicitan en tiempo de ejecución, Android divide los permisos en tipos de instalación (install-time) y ejecución (runtime). El nivel normal se concede automáticamente al instalar sin notificación al usuario. El nivel dangerous requiere un diálogo explícito, similar a iOS.

Otra diferencia: en Android, los permisos se agrupan en grupos de permisos. Si el usuario acepta el acceso a la cámara, la aplicación obtiene automáticamente acceso al micrófono, ya que están en el mismo grupo MICROPHONE. En iOS, cada permiso se solicita de forma independiente, sin importar los grupos.

Evolución de los permisos por versiones de Android

Versión de AndroidCambio en el modelo de permisos
Android 1.0–5.xTodos los permisos se conceden en la instalación
Android 6.0 (API 23)Introducción de Runtime Permissions para nivel dangerous
Android 10 (API 29)Scoped Storage: acceso limitado al sistema de archivos
Android 11 (API 30)Auto-reset de permisos: los permisos no utilizados se restablecen
Android 14 (API 34)Permisos en tiempo de ejecución para acceso multimedia (foto, video, audio)

¿Qué tipos de permisos existen?

Android define cuatro niveles de protección para los permisos, cada uno con sus propias reglas de concesión. Analicemos cada nivel en detalle.

Permisos Normal (install-time)

Los permisos normal se conceden automáticamente al instalar la aplicación sin notificación ni solicitud al usuario. Cubren funciones de bajo riesgo que no amenazan la privacidad del usuario: INTERNET, ACCESS_NETWORK_STATE, VIBRATE, BLUETOOTH. El usuario no ve ningún diálogo de consentimiento: el permiso se considera concedido desde la instalación.

El desarrollador no necesita gestionar solicitudes en tiempo de ejecución para los permisos normal — basta con declararlos en el manifiesto. Sin embargo, en Android 12+, al instalar desde Google Play, el usuario ve una pestaña “Permisos” que enumera todos los permisos normal, lo que aumenta la transparencia. Según Statista (2024), más del 90% de las aplicaciones en Google Play usan INTERNET como el permiso normal más común.

Permisos Dangerous (runtime)

Los permisos dangerous cubren el acceso a datos y funciones que pueden comprometer la privacidad: cámara, micrófono, geolocalización, contactos, SMS, teléfono, calendario, sensores corporales. Estos permisos requieren un mecanismo de dos pasos: declaración en el manifiesto + solicitud en tiempo de ejecución mediante ActivityCompat.requestPermissions().

El usuario puede denegar un permiso dangerous, y la aplicación debe manejar este escenario correctamente. En Android 11+, si el usuario deniega dos veces, las solicitudes posteriores no muestran el diálogo del sistema: el sistema devuelve automáticamente DENIED. En este caso, la aplicación debe dirigir al usuario a los ajustes.

Permisos Signature y Special

El nivel signature: el permiso se concede automáticamente si la aplicación está firmada con el mismo certificado que el sistema u otra aplicación que definió el permiso. Se usa para aplicaciones de sistema y empresariales. Ejemplo: BIND_ACCESSIBILITY_SERVICE, solo disponible para aplicaciones del sistema.

El nivel special (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, REQUEST_INSTALL_PACKAGES, MANAGE_EXTERNAL_STORAGE) requiere una acción explícita del usuario a través de los ajustes del sistema. La aplicación puede abrir la página de ajustes con Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION). Google Play restringe el uso de permisos special y requiere una justificación en el formulario de publicación.

Runtime Permission: trabajar con permisos dangerous

Desde Android 6.0, todos los permisos dangerous requieren solicitud en tiempo de ejecución. Veamos el ciclo completo de trabajo con runtime permissions en Kotlin.

Comprobación y solicitud de permisos

Antes de llamar a una API que requiera un permiso dangerous, verifica siempre el estado actual mediante ContextCompat.checkSelfPermission(). Si el estado es PERMISSION_GRANTED, puedes llamar a la API. Si es PERMISSION_DENIED, debes solicitar el permiso mediante ActivityResultContract RequestPermission (AndroidX) o el obsoleto requestPermissions().

Se recomienda usar ActivityResultContracts.RequestMultiplePermissions para solicitar varios permisos a la vez. Google recomienda agrupar permisos relacionados (por ejemplo, cámara + micrófono para grabación de video) en un solo diálogo, para que el usuario vea el contexto completo de la solicitud.

kotlin
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat

class CameraActivity : AppCompatActivity() {
    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                openCamera()
            } else {
                explainWhyPermissionNeeded()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkCameraPermission()
    }

    private fun checkCameraPermission() {
        when {
            ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED -> {
                openCamera()
            }
            shouldShowRequestPermissionRationale(
                Manifest.permission.CAMERA
            ) -> {
                showRationale()
            }
            else -> {
                requestPermissionLauncher.launch(
                    Manifest.permission.CAMERA
                )
            }
        }
    }
}

Manejo de la denegación “No volver a preguntar”

Si el usuario deniega dos veces, Android pasa la solicitud al estado “Never ask again”. En este caso, shouldShowRequestPermissionRationale() devuelve false y el diálogo del sistema no se mostrará. La aplicación debe dirigir al usuario a los ajustes del sistema mediante Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).

Importante: no muestres un diálogo ofreciendo abrir ajustes inmediatamente después de la primera denegación, ya que se percibe como un comportamiento agresivo. Usa shouldShowRequestPermissionRationale() para determinar si es necesario mostrar una explicación. Material Design Guidelines recomiendan mostrar una pantalla explicando el valor del acceso, no solo un botón de “Abrir ajustes”.

kotlin
private fun openAppSettings() {
    Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", packageName, null)
    ).also { intent ->
        startActivity(intent)
    }
}

private fun showPermissionSettings() {
    AlertDialog.Builder(this)
        .setTitle("Acceso a la cámara")
        .setMessage("Permite el acceso a la cámara en Ajustes, "
            + "para tomar fotos de perfil")
        .setPositiveButton("Abrir ajustes") { _, _ ->
            openAppSettings()
        }
        .setNegativeButton("Cancelar", null)
        .show()
}

Declaración de permisos en AndroidManifest.xml

El archivo AndroidManifest.xml contiene el elemento para cada permiso que utiliza la aplicación. Los permisos se declaran a nivel de antes del elemento .

Sintaxis de declaración

Cada permiso se declara con un elemento independiente con el atributo android:name que especifica el nombre completo del permiso. Para permisos introducidos en versiones específicas de Android, usa el atributo maxSdkVersion para limitar la declaración solo a las versiones necesarias: esto mejora la compatibilidad.

Por ejemplo, el permiso WRITE_EXTERNAL_STORAGE no es necesario en Android 10+ (Scoped Storage), por lo que debes especificar maxSdkVersion="28" (Android 9). Esto evita preguntas innecesarias de los usuarios en versiones más recientes. Android Studio advierte sobre los maxSdkVersion recomendados mediante Lint.

xml
<!-- AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Normal permissions (install-time) -->
    <uses-permission
        android:name="android.permission.INTERNET" />
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Dangerous permissions (runtime) -->
    <uses-permission
        android:name="android.permission.CAMERA" />
    <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Legacy storage permission limited to API 28 and below -->
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="28" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

    <application>
        <!-- ... -->
    </application>
</manifest>

Uso de para filtrado

El elemento indica que la aplicación requiere un hardware específico (cámara, GPS, NFC). El atributo android:required="false" permite instalar la aplicación en dispositivos sin ese hardware: la disponibilidad se comprueba en el código. Si required="true", Google Play filtra la aplicación y no estará disponible para dispositivos no compatibles.

Se recomienda establecer required="false" para todas las funciones de hardware y comprobar la disponibilidad mediante PackageManager.hasSystemFeature(). Esto amplía la audiencia de tu aplicación. La única excepción es si la función es crítica para el funcionamiento de la aplicación (una app de taxi sin GPS no tiene sentido).

Mejores prácticas y errores

El manejo correcto de permisos es un aspecto clave de la calidad de una aplicación Android. Revisemos las principales recomendaciones y errores típicos.

Minimizar los permisos solicitados

Solicita solo los permisos que realmente sean necesarios para el funcionamiento de la aplicación. Cada permiso adicional reduce la tasa de conversión de instalaciones y aumenta la cantidad de denegaciones. Google Play Console muestra cuántos usuarios rechazaron la instalación debido al conjunto de permisos. Según AppBrain (2024), las aplicaciones con 10+ permisos dangerous tienen un 35% menos de instalaciones.

Revisa periódicamente la lista de permisos. Elimina los no utilizados, especialmente al migrar a versiones más recientes de Android donde algunos permisos se vuelven opcionales. Por ejemplo, con el selector de fotos (ActivityResultContracts.PickVisualMedia) en Android 13+, se puede acceder a la biblioteca multimedia sin el permiso dangerous READ_MEDIA_IMAGES.

Mostrar explicación antes de solicitar

Antes de solicitar un permiso dangerous, muestra al usuario una pantalla explicando por qué se necesita ese permiso y qué valor aporta. Material Design recomienda usar una hoja inferior (bottom sheet) o un diálogo con un icono, texto breve y un botón de “Continuar”. La explicación aumenta el consentimiento entre un 20% y un 30% en comparación con una solicitud directa.

Verifica shouldShowRequestPermissionRationale() antes de llamar a launch(). Si es true, muestra la explicación. Si es false, el permiso ya está concedido o el usuario lo ha denegado permanentemente (never ask again). En este último caso, muestra un botón de “Abrir ajustes” en lugar de repetir la solicitud.

Probar todos los escenarios de permisos

Prueba todos los escenarios posibles: concesión del permiso, denegación, denegación permanente, revocación del permiso en ajustes, restablecimiento de permisos (Android 11+ auto-reset). Cada escenario debe manejarse sin fallos ni pérdida de datos. Android Testing Guide recomienda usar la biblioteca TestPermission para automatizar las pruebas.

Presta especial atención al escenario en el que el usuario revoca un permiso mientras la aplicación está en ejecución (aplicación minimizada → Ajustes → revocación). Al volver a la aplicación, verifica todos los permisos en onResume(). No confíes en el almacenamiento en caché del estado de los permisos: el usuario puede cambiarlos en cualquier momento.

Errores típicos

  • Solicitar un permiso sin verificar primero checkSelfPermission: genera un diálogo innecesario
  • Ignorar shouldShowRequestPermissionRationale: empeora la experiencia de usuario tras la primera denegación
  • Solicitar un permiso sin contexto (solo “¿Permitir acceso?”): reduce el consentimiento
  • Usar WRITE_EXTERNAL_STORAGE en Android 10+ sin maxSdkVersion: solicitud innecesaria
  • No verificar permisos en onResume: pasar por alto la revocación de permisos en ajustes

Preguntas frecuentes

¿Es necesario declarar un permiso si lo solicita un SDK?

Sí, si un SDK incluye un permiso en su manifiesto, se fusiona con el manifiesto de la aplicación durante la compilación. Puedes eliminar un permiso innecesario del SDK usando tools:node="remove" en AndroidManifest.xml.

¿Qué ocurre si no se maneja la denegación de un permiso?

Llamar a una API sin permiso generará una SecurityException, lo que provocará un cierre inesperado de la aplicación. Verifica siempre el estado del permiso antes de usar la API correspondiente y maneja la denegación correctamente.

¿Cómo restablecer los permisos durante el desarrollo?

En los ajustes del dispositivo: Ajustes → Aplicaciones → [tu aplicación] → Permisos. Para restablecer todos los permisos, usa el comando adb: adb shell pm reset-permissions.

¿Se puede solicitar un permiso sin una Activity?

Sí, mediante ActivityResultLauncher en un Fragment o Service. Sin embargo, el diálogo de solicitud siempre requiere un contexto de UI de Activity. Para un Service, puedes mostrar una Notification con un Intent que abra la Activity de solicitud.

¿Por qué se necesita maxSdkVersion para los permisos?

Por ejemplo, WRITE_EXTERNAL_STORAGE no es necesario en Android 10+ (Scoped Storage). Al especificar android:maxSdkVersion="28", excluyes la declaración del permiso en versiones nuevas, lo que mejora la compatibilidad y reduce la lista de permisos solicitados.

Resumen

  • AndroidManifest Permissions: declaraciones obligatorias para acceder a recursos del sistema en Android
  • 4 niveles de protección: normal, dangerous, signature, special con diferentes mecanismos de concesión
  • Runtime Permissions: los permisos dangerous requieren solicitud en tiempo de ejecución (Android 6+)
  • Grupos de permisos: el consentimiento a un permiso en un grupo concede acceso a todos los del grupo
  • Explicación: mostrar una explicación antes de solicitar aumenta el consentimiento entre un 20% y un 30%
  • Minimización: solicita solo los permisos necesarios y usa maxSdkVersion
  • Verifica siempre el estado del permiso antes de llamar a una API y maneja todos los escenarios de denegación

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