Descripción general del manifiesto de una app

Todos los proyectos de apps deben tener un archivo AndroidManifest.xml (con ese mismo nombre) en la raíz de la fuente del proyecto. El archivo de manifiesto describe información esencial de tu aplicación para las herramientas de creación de Android, el sistema operativo Android y Google Play.

Entre muchas otras cosas, el archivo de manifiesto debe declarar lo siguiente:

  • El nombre del paquete de la aplicación, que normalmente coincide con el espacio de nombres de tu código. Las herramientas de compilación de Android usan esto para determinar la ubicación de las entidades de código cuando se compila el proyecto. Al empaquetar la aplicación, las herramientas de compilación sustituyen este valor por el ID de aplicación de los archivos de compilación de Gradle, que se utiliza como identificador único de la aplicación en el sistema y en Google Play. Obtén más información sobre el nombre del paquete y el ID de la aplicación.
  • Los componentes de la aplicación, que incluyen todas las actividades, servicios, receptores de emisiones y proveedores de contenido. Cada componente debe definir propiedades básicas, como el nombre de su clase Kotlin o Java. También puede declarar capacidades, como las configuraciones de dispositivos que puede manejar, además de filtros de intents que describen cómo se puede iniciar el componente. Obtén más información sobre los componentes de la aplicación.
  • Los permisos que necesita la aplicación para acceder a las partes protegidas del sistema o a otras aplicaciones. También declara cualquier permiso que otras aplicaciones deben tener si quieren acceder al contenido de esta aplicación. Obtén más información sobre los permisos.
  • Las funciones de hardware y software que requiere la aplicación afectan a los dispositivos que pueden instalar la aplicación desde Google Play. Obtén más información sobre la compatibilidad de dispositivos.

Si usas Android Studio para crear una aplicación, se generará el archivo de manifiesto automáticamente, y la mayoría de los elementos esenciales de este se irán agregando a medida que compiles la aplicación (especialmente cuando uses plantillas de código).

Funciones del archivo

Las siguientes secciones describen cómo algunas de las características más importantes de tu aplicación se reflejan en el archivo de manifiesto.

Nombre del paquete e ID de la aplicación

El elemento raíz del archivo de manifiesto requiere un atributo para el nombre del paquete de tu aplicación (que normalmente coincide con la estructura del directorio del proyecto: el espacio de nombres de Java).

Por ejemplo, el siguiente fragmento muestra el elemento raíz <manifest> con el nombre de paquete "com.example.myapp":

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp"
    android:versionCode="1"
    android:versionName="1.0" >
    ...
</manifest>

Mientras compilas tu aplicación en el paquete de aplicación final (APK), las herramientas de compilación de Android utilizan el atributo package para dos cosas:

  • Aplica este nombre como espacio de nombres para la clase R.java generada de tu app (se usa para acceder a los recursos de la aplicación).

    Ejemplo: Con el manifiesto anterior, se crea la clase R en com.example.myapp.R.

  • Usa este nombre para resolver cualquier nombre de clase relativo que se declare en el archivo de manifiesto.

    Ejemplo: Con el manifiesto anterior, se resuelve una actividad declarada como <activity android:name=".MainActivity"> y pasa a ser com.example.myapp.MainActivity.

Como tal, el nombre del atributo package del manifiesto siempre debe coincidir con el nombre de paquete básico de tu proyecto, en el cual conservas tus actividades y otros tipos de código de la app. Por supuesto, puedes tener otros subpaquetes en tu proyecto, pero esos archivos deben importar la clase R.java usando el espacio de nombres del atributo package.

Sin embargo, ten en cuenta que, una vez compilado el APK, el atributo package también representa el ID único de tu aplicación. Después de que las herramientas de compilación realizan las tareas anteriores basadas en el nombre package, sustituyen el valor package por el asignado a la propiedad applicationId en el archivo build.gradle de tu proyecto (utilizado en los proyectos de Android Studio). Este valor final del atributo package debe ser único, ya que es la única forma garantizada de identificar tu aplicación en el sistema y en Google Play.

La distinción entre el nombre package en el manifiesto y el objeto applicationId en el archivo build.gradle puede ser un poco confusa. Sin embargo, si son iguales, no deberás preocuparte.

Ahora bien, si decides hacer que el espacio de nombres del código (y, por lo tanto, el nombre de package en el manifiesto) difiera del objeto applicationId del archivo de compilación, asegúrate de entender las consecuencias de cambiar el ID de la aplicación. Esa página explica cómo modificar de forma segura el nombre del objeto package del manifiesto, independientemente del objeto applicationId del archivo de compilación, y cómo cambiar el ID de la aplicación para diferentes configuraciones de compilación.

Componentes de la aplicación

Por cada componente de app que crees en tu aplicación, deberás declarar un elemento XML correspondiente en el archivo de manifiesto:

Si incluyes en subclases cualquiera de estos componentes sin declararlo en el archivo de manifiesto, el sistema no podrá iniciarlo.

El nombre de la subclase debe especificarse con el atributo name, utilizando la designación del paquete completo. Por ejemplo, una subclase Activity podría declararse de la siguiente manera:

<manifest ... >
    <application ... >
        <activity android:name="com.example.myapp.MainActivity" ... >
        </activity>
    </application>
</manifest>

Sin embargo, si el primer carácter del valor name es un punto, el nombre de paquete de la aplicación (del elemento <manifest> perteneciente al atributo package) se adjunta como prefijo. Por ejemplo, el nombre de la siguiente actividad se verá como `"com.example.myapp.MainActivity"`:

<manifest package="com.example.myapp" ... >
    <application ... >
        <activity android:name=".MainActivity" ... >
            ...
        </activity>
    </application>
</manifest>

Si algunos componentes de tu aplicación están en subpaquetes (como en com.example.myapp.purchases), el valor name debe agregar los nombres de los subpaquetes que faltan (como ".purchases.PayActivity") o utilizar el nombre de paquete completamente calificado.

Filtros de intents

Las actividades, servicios y receptores de emisión de una aplicación se activan mediante intents. Una intent es un mensaje definido por un objeto Intent que describe una acción que se realizará, incluidos los datos sobre los que se debe actuar, la categoría del componente que debe realizar la acción y otras instrucciones.

Cuando una aplicación emite una intent al sistema, el sistema localiza un componente de la aplicación que puede manejar la intent según las declaraciones del filtro de intent en el archivo de manifiesto de cada aplicación. El sistema lanza una instancia del componente correspondiente y pasa el objeto Intent a ese componente. Si más de una aplicación puede manejar la intent, entonces el usuario puede seleccionar qué aplicación usar.

Un componente de aplicación puede tener cualquier número de filtros de intent (definidos con el elemento <intent-filter>), cada uno de los cuales describe una capacidad diferente de ese componente.

Para obtener más información, lee el documento Intents y filtros de intents.

Íconos y etiquetas

Algunos elementos del manifiesto tienen atributos icon y label para mostrar un pequeño ícono y una etiqueta de texto, respectivamente, a los usuarios según el componente de aplicación correspondiente.

En cada caso, el ícono y la etiqueta establecidos en un elemento superior se convierten en la configuración predeterminada de icon y label para todos los elementos inferiores. Por lo tanto, el ícono y la etiqueta establecidos en el elemento <application> son el ícono y la etiqueta predeterminados para cada componente de la aplicación (como todas las actividades).

El ícono y la etiqueta que se establecen en el <intent-filter> de un componente se muestran al usuario siempre que ese componente se presenta como una opción para cumplir una intent. De forma predeterminada, este ícono se hereda de cualquier ícono que se declare para el componente superior (ya sea el elemento <activity> o <application>), pero es posible que quieras cambiar el ícono por un filtro de intent si proporcionas una acción única que te gustaría indicar mejor en el cuadro de diálogo del selector. Para obtener más información, consulta Cómo permitir que otras apps inicien tu actividad.

Permisos

Las aplicaciones de Android deben solicitar permiso para acceder a datos del usuario confidenciales (como contactos y SMS) o a determinadas funciones del sistema (como la cámara y el acceso a Internet). Cada permiso se identifica con una etiqueta única. Por ejemplo, en el manifiesto de una app que necesite enviar mensajes SMS debe incluirse esta línea:

<manifest ... >
    <uses-permission android:name="android.permission.SEND_SMS"/>
    ...
</manifest>

A partir de Android 6.0 (nivel de API 23), el usuario puede aprobar o rechazar algunos permisos durante el tiempo de ejecución. No obstante, sin importar qué versión de Android admita tu aplicación, debes declarar todas las solicitudes de permisos con un elemento <uses-permission> en el manifiesto. Si se otorga el permiso, la aplicación puede usar las funciones protegidas. De lo contrario, los intentos de acceder a esas funciones fallarán.

Tu aplicación también puede proteger sus propios componentes con permisos. Puede usar cualquiera de los permisos definidos por Android, tal como se indica en android.Manifest.permission, o un permiso que esté declarado en otra app. Tu aplicación también puede definir sus propios permisos. Un permiso nuevo se declara con el elemento <permission>.

Para obtener más información, consulta Descripción general de los permisos.

Compatibilidad con dispositivos

En el archivo de manifiesto, también puedes declarar qué tipos de funciones de hardware y software requiere tu aplicación y, por lo tanto, qué tipos de dispositivos admite. Google Play Store no permite que tu app se instale en dispositivos que no tienen las funciones o la versión del sistema que requiere tu app.

Hay varias etiquetas de manifiesto que definen qué dispositivos son compatibles con tu app. A continuación, se incluyen algunas de las más comunes.

<uses-feature>

El elemento <uses-feature> te permite declarar funciones de hardware y software que necesita tu app. Por ejemplo, si tu aplicación no puede funcionar un dispositivo que no tiene un sensor de brújula, puedes declarar el sensor como obligatorio con la siguiente etiqueta de manifiesto:

<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>

Nota: Si quieres que tu app esté disponible para Chromebooks, hay algunas limitaciones importantes de hardware y software que deberías tener en cuenta. Para obtener más información, consulta Compatibilidad de manifiesto de una app para Chromebooks.

<uses-sdk>

Cada versión siguiente de la plataforma suele agregar nuevas API que no están disponibles en la versión anterior. Para indiciar la versión mínima con la que tu app es compatible, tu manifiesto debe incluir la etiqueta <uses-sdk> y su atributo minSdkVersion.

Sin embargo, ten en cuenta que los atributos del elemento <uses-sdk> son anulados por las propiedades correspondientes del archivo build.gradle. Por lo tanto, si usas Android Studio, debes especificar los valores minSdkVersion y targetSdkVersion allí:

android {
  defaultConfig {
    applicationId 'com.example.myapp'

    // Defines the minimum API level required to run the app.
    minSdkVersion 15

    // Specifies the API level used to test the app.
    targetSdkVersion 28

    ...
  }
}

Para obtener más información sobre el archivo build.gradle, lee sobre cómo configurar tu compilación.

Para obtener más información sobre cómo declarar la compatibilidad de tu app con diferentes dispositivos, consulta Descripción general de la compatibilidad de dispositivos.

Convenciones del archivo

En esta sección, se describen las convenciones y las reglas que generalmente se aplican a todos los elementos y atributos del archivo de manifiesto.

Elementos
Solo se requieren los elementos <manifest> y <application>. Deben aparecer una sola vez. La mayoría de los demás elementos pueden aparecer cero o más veces. Sin embargo, algunos deben estar presentes para que se pueda usar el archivo de manifiesto.

Todos los valores se establecen mediante atributos, y no como datos de caracteres en un elemento.

Por lo general, los elementos de un mismo nivel no están ordenados. Por ejemplo, los elementos <activity>, <provider> y <service> se pueden alternar en cualquier secuencia. Hay dos excepciones importantes a esta regla:

Atributos
Técnicamente, todos los atributos son opcionales. Sin embargo, varios deben especificarse para que un elemento pueda cumplir su propósito. En el caso de los atributos que realmente son opcionales, la documentación de referencia indica los valores predeterminados.

Excepto para algunos atributos del elemento raíz <manifest>, todos los nombres de los atributos comienzan con un prefijo android:. Por ejemplo, android:alwaysRetainTaskState. Debido a que el prefijo es universal, en la documentación suele omitirse cuando se hace referencia a los atributos por nombre.

Varios valores
Si se puede especificar más de un valor, el elemento se repite casi siempre, en lugar de que se enumeren varios valores en un único elemento. Por ejemplo, en un filtro de intents se pueden enumerar varias acciones:
<intent-filter ... >
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.INSERT" />
    <action android:name="android.intent.action.DELETE" />
    ...
</intent-filter>
Valores de recursos
Algunos atributos tienen valores que se pueden mostrar a los usuarios, como el título de una actividad o el ícono de una app. Es posible que el valor de estos atributos varíe en función del idioma del usuario y otras configuraciones del dispositivo (como ofrecer otro tamaño de ícono según la densidad de píxeles de la pantalla), de modo que los valores deben establecerse desde un recurso o tema en lugar de un archivo de manifiesto hard-coded. El valor real puede cambiar en función de recursos alternativos que proporcionas para diferentes configuraciones de dispositivos.

Los recursos se expresan como valores con el siguiente formato:

"@[package:]type/name"

Puedes omitir el nombre package si tu aplicación proporciona el recurso (incluso si es proporcionado por una dependencia de la biblioteca, ya que los recursos de biblioteca están fusionados con los tuyos). El otro nombre de paquete válido es android, disponible cuando quieres usar un recurso del marco de trabajo de Android.

type es un tipo de recurso, como string o drawable, y name es el nombre que identifica al recurso específico. A continuación, te mostramos un ejemplo:

<activity android:icon="@drawable/smallPic" ... >

Para obtener más información sobre cómo agregar recursos a tu proyecto, lee Cómo proporcionar recursos.

Si prefieres aplicar un valor definido en el tema, el primer carácter debe ser ? en lugar de @:

"?[package:]type/name"

Valores de strings
Cuando el valor de un atributo sea una string, debes usar doble barra invertida (\\) para diferenciarlo de los caracteres, como \\n para una nueva línea o \\uxxxx para un carácter Unicode.

Referencia de los elementos del manifiesto

La siguiente tabla proporciona vínculos a los documentos de referencia de todos los elementos válidos del archivo AndroidManifest.xml.

<action> Agrega una acción a un filtro de intent.
<activity> Declara el componente de una actividad.
<activity-alias> Declara el alias de una actividad.
<application> Es la declaración de la aplicación.
<category> Agrega el nombre de una categoría a un filtro de intent.
<compatible-screens> Especifica cada configuración de pantalla con la que es compatible la aplicación.
<data> Agrega especificaciones de datos a un filtro de intent.
<grant-uri-permission> Especifica los subconjuntos de datos de aplicaciones a los que el proveedor de contenido principal tiene permiso para acceder.
<instrumentation> Declara una clase Instrumentation que te permite supervisar la interacción de una aplicación con el sistema.
<intent-filter> Especifica los tipos de intents a los que puede responder una actividad, un servicio o un receptor de emisión.
<manifest> Es el elemento raíz del archivo AndroidManifest.xml.
<meta-data> Es un par nombre-valor para un elemento de datos adicionales y arbitrarios que se pueden suministrar al componente superior.
<path-permission> Define la ruta y los permisos necesarios para un subconjunto específico de datos dentro de un proveedor de contenido.
<permission> Declara un permiso de seguridad que puede utilizarse para limitar el acceso a componentes o funciones específicas de esta u otras aplicaciones.
<permission-group> Declara un nombre para una agrupación lógica de permisos relacionados.
<permission-tree> Declara el nombre base de un árbol de permisos.
<provider> Declara el componente de un proveedor de contenido.
<receiver> Declara el componente de un receptor de emisión.
<service> Declara el componente de un servicio.
<supports-gl-texture> Declara un único formato de compresión de textura GL que admite la aplicación.
<supports-screens> Declara los tamaños de pantalla que admite tu aplicación y habilita el modo de compatibilidad para pantallas más grandes que las que admite tu aplicación.
<uses-configuration> Indica las funciones específicas de entrada que requiere la aplicación.
<uses-feature> Declara una sola función de hardware o software que usa la aplicación.
<uses-library> Especifica una biblioteca compartida con la que debe vincularse la aplicación.
<uses-permission> Especifica un permiso de sistema que debe conceder el usuario para que la aplicación funcione correctamente.
<uses-permission-sdk-23> Especifica que una app desea un permiso particular, pero solo si esta se ejecuta en un dispositivo que ejecuta Android 6.0 (nivel de API 23) o versiones posteriores.
<uses-sdk> Te permite expresar la compatibilidad de una aplicación con una o más versiones de la plataforma Android, a través de un valor entero de nivel de API.

Ejemplo de archivo de manifiesto

El XML que aparece a continuación es un AndroidManifest.xml simple de ejemplo que declara dos actividades de la aplicación.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="com.example.myapp">

    <!-- Beware that these values are overridden by the build.gradle file -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- This name is resolved to com.example.myapp.MainActivity
             based upon the package attribute -->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DisplayMessageActivity"
            android:parentActivityName=".MainActivity" />
    </application>
</manifest>