Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Cómo fusionar varios archivos de manifiesto

Tu archivo de APK puede contener solo un archivo AndroidManifest.xml, pero tu proyecto de Android Studio puede tener varios, ya que el conjunto principal de fuentes, variantes de compilaciones y bibliotecas importadas pueden proporcionarlos. Por lo tanto, cuando creas tu app, la compilación de Gradle fusiona todos los archivos de manifiesto en un único archivo de manifiesto empaquetado en tu APK.

La herramienta de fusión de manifiesto combina todos los elementos XML de cada archivo mediante una heurística de fusión y de acuerdo con las preferencias de fusión definidas con atributos XML especiales. En esta página, se describe el funcionamiento de la fusión de manifiesto y la aplicación de preferencias de fusión para resolver conflictos.

Sugerencia: Usa la vista Merged Manifest para obtener una vista previa de los resultados de tu manifiesto fusionado y detectar errores de conflicto.

Prioridades de fusión

La herramienta de fusión combina todos los archivos de manifiesto en un solo archivo. Para ello, fusiona los archivos de manifiesto de manera secuencial según la prioridad de cada uno. Por ejemplo, si tienes tres archivos de manifiesto, el manifiesto de menor prioridad se fusiona con el de prioridad superior que sigue, y a su vez estos archivos fusionados se vuelven a fusionar con el manifiesto de mayor prioridad, como se ilustra en la figura 1.

Figura 1: Proceso de fusión de tres archivos de manifiesto, de menor prioridad (izquierda) a mayor prioridad (derecha)

Existen tres tipos básicos de archivos de manifiesto que pueden fusionarse. A continuación, se indican sus prioridades de fusión (la mayor prioridad primero):

  1. Archivo de manifiesto para tu variante de compilación

    Si tienes varios conjuntos de fuentes para tu variante, las prioridades de manifiesto son las siguientes:

    1. Manifiesto de variantes de compilación (como src/demoDebug/)
    2. Manifiesto de tipo de compilación (como src/debug/)
    3. Manifiesto de tipo de producto (como src/demo/)

      Si usas dimensiones de tipo, las prioridades de manifiesto corresponden al orden en que se enumera cada dimensión en la propiedad flavorDimensions (la mayor prioridad primero).

  2. Archivo de manifiesto principal para el módulo de la app
  3. Archivo de manifiesto de una biblioteca incluida

    Si tienes varias bibliotecas, las prioridades de manifiestos de estas coinciden con el orden de dependencia (el orden en que aparecen en tu bloque dependencies de Gradle).

Por ejemplo, un manifiesto de biblioteca se fusiona en el manifiesto principal y luego este último se fusiona con el manifiesto de la variante de compilación.

Importante: Las configuraciones de compilación del archivo build.gradle anulan cualquier atributo coincidente en los archivos de manifiesto fusionados. Por ejemplo, minSdkVersion del archivo build.gradle anula el atributo coincidente en el elemento de manifiesto <uses-sdk>. Para evitar confusiones, solo debes dejar afuera el elemento <uses-sdk> y definir estas propiedades únicamente en el archivo build.gradle. Para obtener información detallada, consulta Configura tu compilación.

Heurística de conflictos de fusión

La herramienta de fusión puede unir de manera lógica cada elemento XML de un manifiesto con un elemento coincidente del otro manifiesto. (Para obtener detalles sobre el funcionamiento del mecanismo de coincidencia, consulta el apéndice sobre políticas de fusión).

Si un elemento del manifiesto de prioridad inferior no coincide con ningún elemento del manifiesto de prioridad superior, se agregará al manifiesto fusionado. Sin embargo, si hay un elemento coincidente, la herramienta de fusión intenta combinar todos los atributos de cada uno en el mismo elemento. Si la herramienta detecta que ambos manifiestos contienen el mismo atributo con diferentes valores, se produce un conflicto de fusión.

En la tabla 1, se ilustran los posibles resultados que pueden generarse cuando una herramienta de fusión intenta combinar todos los atributos en el mismo elemento.

Tabla 1. Comportamiento de fusión predeterminado para valores de atributo

Atributo de prioridad alta Atributo de prioridad baja Resultado fusionado del atributo
Sin valor Sin valor Sin valor (usar valor predeterminado)
Valor B Valor B
Valor A Sin valor Valor A
Valor A Valor A
Valor B Error de conflicto: Debes agregar un marcador de regla de fusión

Sin embargo, existen algunas situaciones en las que la herramienta de fusión se comporta de manera diferente para evitar conflictos de fusión:

  • Los atributos del elemento <manifest> nunca se fusionan; solo se usan los atributos del manifiesto de mayor prioridad.
  • El atributo android:required en los elementos <uses-feature> y <uses-library> usa una combinación O de modo que, si hay un conflicto, se aplique "true" y siempre se incluya la característica o biblioteca requerida por un manifiesto.
  • Los atributos en el elemento <uses-sdk> siempre usan el valor del manifiesto de prioridad superior, excepto en las siguientes situaciones:
    • Cuando el manifiesto de prioridad inferior tiene un valor minSdkVersion que es mayor, se produce un error a menos que apliques la regla de fusión overrideLibrary.
    • Cuando el manifiesto de prioridad inferior tiene un valor de targetSdkVersion inferior, la herramienta de fusión usa el valor del manifiesto de prioridad superior, pero también agrega cualquier permiso del sistema que se necesite para garantizar que la biblioteca importada continúe funcionando correctamente (para casos en que la versión posterior de Android tenga mayores restricciones de permisos). Para obtener más información sobre este comportamiento, consulta la sección sobre permisos implícitos del sistema.
  • El elemento <intent-filter> nunca coincide entre diferentes manifiestos. Cada uno recibe tratamiento exclusivo y se agrega al elemento principal común en el manifiesto fusionado.

Para todos los demás conflictos entre atributos, aparecerá un error y deberás indicar a la herramienta de fusión la manera de corregirlo. Para ello, debes agregar un atributo especial en el archivo de manifiesto de prioridad superior (consulta la siguiente sección sobre marcadores de reglas de fusión).

No dependas de los valores de atributos predeterminados. Como todos los atributos únicos se combinan en el mismo elemento, es posible que se produzcan resultados inesperados si el manifiesto de prioridad superior en realidad depende del valor predeterminado de un atributo sin declararlo. Por ejemplo, si el manifiesto de prioridad superior no declara el atributo android:launchMode, usará el valor predeterminado "standard"; pero si el manifiesto de prioridad inferior declara este atributo con un valor diferente, se aplicará ese valor al manifiesto fusionado (y se anulará el valor predeterminado). Debes definir cómo deseas que sea cada atributo de manera explícita. (Los valores predeterminados de cada atributo se documentan en la referencia del manifiesto).

Marcadores de reglas de fusión

Un marcador de reglas de fusión es un atributo XML que puedes usar para expresar tu preferencia a fin de resolver conflictos de fusión o quitar elementos y atributos no deseados. Puedes aplicar un marcador a un elemento entero o solo a atributos específicos de un elemento.

Al fusionar dos archivos de manifiesto, la herramienta de fusión busca estos marcadores en el archivo de manifiesto de prioridad superior.

Todos los marcadores pertenecen al espacio de nombres tools de Android; por ello, primero debes declarar este espacio de nombres en el elemento <manifest>, como se observa a continuación:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp"
        xmlns:tools="http://schemas.android.com/tools">
    

Marcadores de nodos

Para aplicar una regla de fusión a un elemento XML completo (a todos los atributos de un elemento de manifiesto específico y a todas sus etiquetas secundarias), usa los siguientes atributos:

tools:node="merge"
Fusiona todos los atributos de esta etiqueta y todos los elementos anidados cuando no hay conflictos usando la heurística de conflictos de fusión. Este es el comportamiento predeterminado de los elementos.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="merge">
    </activity>
    

Resultado del manifiesto fusionado:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
tools:node="merge-only-attributes"
Fusiona solo los atributos de esta etiqueta, no fusiones los elementos anidados.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <data android:type="image/*" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="merge-only-attributes">
    </activity>
    

Resultado del manifiesto fusionado:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
    </activity>
    
tools:node="remove"
Quita este elemento del manifiesto fusionado. Aunque parezca que debes borrar este elemento, cuando descubras en tu manifiesto fusionado un elemento que no necesites y que se haya proporcionado a través de un archivo de manifiesto de prioridad inferior que esté fuera de tu control (como una biblioteca importada), deberás usar esta opción.

Manifiesto de prioridad baja:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

Manifiesto de prioridad alta:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          tools:node="remove"/>
    </activity-alias>
    

Resultado del manifiesto fusionado:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    
tools:node="removeAll"
Es similar a tools:node="remove", pero quita todos los elementos que coinciden con este tipo de elemento (dentro del mismo elemento principal).

Manifiesto de prioridad baja:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

Manifiesto de prioridad alta:

    <activity-alias android:name="com.example.alias">
      <meta-data tools:node="removeAll"/>
    </activity-alias>
    

Resultado del manifiesto fusionado:

    <activity-alias android:name="com.example.alias">
    </activity-alias>
    
tools:node="replace"
Reemplaza el elemento de prioridad inferior por completo. Es decir, si hay un elemento coincidente en el manifiesto de prioridad inferior, ignóralo y usa este elemento exactamente como aparece en este manifiesto.

Manifiesto de prioridad baja:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

Manifiesto de prioridad alta:

    <activity-alias android:name="com.example.alias"
        tools:node="replace">
      <meta-data android:name="fox"
          android:value="@string/dingeringeding"/>
    </activity-alias>
    

Resultado del manifiesto fusionado:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="fox"
          android:value="@string/dingeringeding"/>
    </activity-alias>
    
tools:node="strict"
Genera una falla de compilación cada vez que este elemento del manifiesto de prioridad inferior no coincida exactamente con el elemento del manifiesto de prioridad superior (salvo que se resuelva a través de otros marcadores de reglas de fusión). De esta manera, se anula la heurística de conflictos de fusión. Por ejemplo, si en el manifiesto de prioridad inferior simplemente se incluye un atributo adicional, la compilación falla (mientras que el comportamiento predeterminado agrega el atributo adicional al manifiesto fusionado).

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="strict">
    </activity>
    

De esta manera, se crea un error de fusión de manifiestos. Los dos elementos de manifiestos no pueden diferir de ninguna manera en el modo estricto. Por ello, debes aplicar otros marcadores de reglas de fusión para resolver estas diferencias. (Generalmente, estos dos se fusionarán de manera correcta, como se observa en el ejemplo anterior de tools:node="merge").

Marcadores de atributos

Para aplicar una regla de fusión solo a atributos específicos en una etiqueta de manifiesto, usa los siguientes atributos. Cada atributo acepta uno o más nombres (incluido el espacio de nombres de los atributos), separados por coma.

tools:remove="attr, ..."
Quita los atributos especificados del manifiesto fusionado. Aunque parezca que podrías borrar estos atributos, cuando el archivo de prioridad inferior incluye estos atributos y quieres asegurarte de que no se incluyan en el manifiesto fusionado, debes usar esta opción.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:remove="android:windowSoftInputMode">
    

Resultado del manifiesto fusionado:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait">
    
tools:replace="attr, ..."
Reemplaza los atributos especificados en el manifiesto de menor prioridad por los de este manifiesto. Es decir, conserva siempre los valores de los manifiestos de prioridad superior.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:theme="@oldtheme"
        android:exported="false"
        android:windowSoftInputMode="stateUnchanged">
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        tools:replace="android:theme,android:exported">
    

Resultado del manifiesto fusionado:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
    
tools:strict="attr, ..."
Genera una falla de compilación cada vez que estos elementos del manifiesto de prioridad inferior no coincidan exactamente con el elemento del manifiesto de prioridad superior. Este es el comportamiento predeterminado de todos los atributos, excepto aquellos con comportamientos especiales, como se describe en la heurística de conflictos de fusión.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="landscape">
    </activity>
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:strict="android:screenOrientation">
    </activity>
    

De esta manera, se crea un error de fusión de manifiestos. Para resolver este conflicto, debes aplicar otros marcadores de reglas de fusión. (Recuerda que este es el comportamiento predeterminado; por ello, el ejemplo anterior tiene el mismo resultado si quitas tools:strict="screenOrientation").

También puedes aplicar varios marcadores a un elemento, como se describe a continuación.

Manifiesto de prioridad baja:

    <activity android:name="com.example.ActivityOne"
        android:theme="@oldtheme"
        android:exported="false"
        android:allowTaskReparenting="true"
        android:windowSoftInputMode="stateUnchanged">
    

Manifiesto de prioridad alta:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        tools:replace="android:theme,android:exported"
        tools:remove="android:windowSoftInputMode">
    

Resultado del manifiesto fusionado:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:allowTaskReparenting="true"
        android:screenOrientation="portrait">
    

Selector de marcadores

Si deseas aplicar los marcadores de reglas de fusión solo a una biblioteca importada específica, agrega el atributo tools:selector con el nombre del paquete de la biblioteca.

Por ejemplo, con el siguiente manifiesto, la regla de fusión remove solo se aplica cuando el archivo de manifiesto de prioridad inferior pertenece a la biblioteca com.example.lib1.

    <permission android:name="permissionOne"
        tools:node="remove"
        tools:selector="com.example.lib1">
    

Si el manifiesto de prioridad inferior pertenece a otra fuente, se ignora la regla de fusión remove.

Nota: Si usas este procedimiento con uno de los marcadores de atributos, este se aplicará a todos los atributos especificados en el marcador.

Cómo anular <uses-sdk> para las bibliotecas importadas

De forma predeterminada, si importas una biblioteca con un valor minSdkVersion superior al del archivo de manifiesto principal, se produce un error y no es posible importar la biblioteca. Para que la herramienta de fusión ignore este conflicto, importe la biblioteca y, al mismo tiempo, mantenga el valor minSdkVersion inferior de tu app, agrega el atributo overrideLibrary a la etiqueta <uses-sdk>. El valor del atributo puede ser uno o más nombres de paquetes de bibliotecas (separados por comas), que indiquen las bibliotecas que pueden anular el valor minSdkVersion del manifiesto principal.

Por ejemplo, si el manifiesto principal de tu app aplica overrideLibrary de la siguiente forma:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.app"
              xmlns:tools="http://schemas.android.com/tools">
      <uses-sdk tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
    ...
    

El siguiente manifiesto se puede fusionar sin errores relacionados con la etiqueta <uses-sdk> y el manifiesto fusionado mantiene el valor minSdkVersion="2" del manifiesto de la app.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.lib1">
       <uses-sdk android:minSdkVersion="4" />
    ...
    

Permisos del sistema implícitos

Algunas API de Android que solían ser de libre acceso por medio de las apps ahora están restringidas por permisos del sistema en versiones recientes de Android. Para evitar daños en apps que buscan acceso a estas API, las últimas versiones de Android permiten que las apps continúen accediendo a estas API sin permiso si establecieron targetSdkVersion en un valor inferior al de la versión en la que se agregó la restricción. Este comportamiento efectivamente otorga a la app un permiso implícito para que acceda a las API. De esta manera, los manifiestos fusionados que tienen diferentes valores para targetSdkVersion pueden resultar afectados, como se indica a continuación.

Si el archivo de manifiesto de menor prioridad tiene un valor de targetSdkVersion inferior que le otorga un permiso implícito, y el manifiesto de prioridad superior no tiene el mismo permiso implícito (porque su targetSdkVersion es igual o superior al de la versión en la que se agregó la restricción), la herramienta de fusión explícitamente agrega el permiso del sistema al manifiesto fusionado.

Por ejemplo, si tu app establece targetSdkVersion en 4 o un valor superior y, luego, importa una biblioteca con targetSdkVersion establecido en 3 o un valor inferior, la herramienta de fusión agrega el permiso WRITE_EXTERNAL_STORAGE al manifiesto fusionado. En la tabla 2, se enumeran todos los posibles permisos que se pueden agregar a tu manifiesto fusionado.

Tabla 2. Lista de permisos que la herramienta de fusión puede agregar al manifiesto fusionado

El manifiesto de prioridad inferior declara Permisos agregados al manifiesto fusionado
targetSdkVersion es 3 o menor WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion es 15 o menor y usa READ_CONTACTS READ_CALL_LOG
targetSdkVersion es 15 o menor y usa WRITE_CONTACTS WRITE_CALL_LOG

Cómo inspeccionar el manifiesto fusionado y buscar conflictos

Incluso antes de compilar tu APK, puedes obtener una vista previa de tu manifiesto fusionado. Para ello, debes abrir tu archivo AndroidManifest.xml en Android Studio y hacer clic en la pestaña Manifiesto fusionado que se encuentra en la parte inferior del editor.

En la vista Manifiesto fusionado, se muestran los resultados de este en la parte izquierda y se incluye información sobre cada manifiesto fusionado a la derecha, como se observa en la figura 2. Los elementos fusionados a partir de archivos de manifiesto de prioridad inferior se destacan en diferentes colores, a la izquierda. El significado de cada color se especifica en Fuentes del manifiesto, a la derecha.

Figura 2: La vista Manifiesto fusionado

Los archivos de manifiesto que formaron parte de la compilación pero que no aportaron elementos ni atributos se detallan en Otros archivos del manifiesto, a la derecha.

Para ver información sobre el origen de un elemento, haz clic sobre un elemento en la parte izquierda. Podrás ver los detalles en Registro de fusiones, a la derecha.

Si se produce algún conflicto, este aparecerá en Errores de fusión, en la parte derecha con una recomendación sobre cómo resolver el conflicto usando los marcadores de reglas de fusión. También se incluyen errores impresos en la ventana Registro de eventos (selecciona Ver > Ventanas de herramientas > Registro de eventos).

Si deseas ver un registro completo del árbol de decisiones de fusión, puedes buscar el archivo de registro en el directorio build/outputs/logs/ de tu módulo, denominado manifest-merger-buildVariant-report.txt.

Apéndice: Políticas de fusión

La herramienta de fusión de manifiestos puede unir de manera lógica cada elemento XML de un archivo de manifiesto con un elemento coincidente de otro archivo. La herramienta une los elementos a través de una "clave de coincidencia", que puede ser un valor de atributo único (como android:name) o la exclusividad natural de la propia etiqueta (por ejemplo, puede haber un solo elemento <supports-screen>). Si los dos manifiestos tienen el mismo elemento XML, la herramienta los fusiona con una de las tres políticas de fusión:

Fusionar
Combina todos los atributos sin conflictos en la misma etiqueta y fusiona los elementos secundarios según sus respectivas políticas de fusión. Si alguno de los atributos tiene un conflicto con otro, los fusiona con los marcadores de reglas de fusión.
Fusionar solo elementos secundarios
No combina ni fusiona los atributos (mantiene únicamente los atributos provistos por el archivo de manifiesto de mayor prioridad), y fusiona los elementos secundarios según sus políticas de fusión.
Conservar
Deja el elemento "como se encuentra" y lo agrega al elemento principal común en el archivo fusionado. Esta opción solo se usa cuando es aceptable que haya diferentes declaraciones del mismo elemento.

En la tabla 3, se enumera cada tipo de elemento, el tipo de política de fusión empleado y la clave usada para determinar la coincidencia de elementos entre dos manifiestos.

Tabla 3. Claves de coincidencia y políticas de fusión de elementos de manifiesto

Elemento Política de fusión Clave de coincidencia
<action> Fusionar Atributo android:name
<activity> Fusionar Atributo android:name
<application> Fusionar Solo hay uno por <manifest>
<category> Fusionar Atributo android:name
<data> Fusionar Solo hay uno por <intent-filter>
<grant-uri-permission> Fusionar Solo hay uno por <provider>
<instrumentation> Fusionar Atributo android:name
<intent-filter> Conservar Sin coincidencia; se permiten varias declaraciones dentro del elemento principal
<manifest> Fusionar solo elementos secundarios Solo hay uno por archivo.
<meta-data> Fusionar Atributo android:name
<path-permission> Fusionar Solo hay uno por <provider>
<permission-group> Fusionar Atributo android:name
<permission> Fusionar Atributo android:name
<permission-tree> Fusionar Atributo android:name
<provider> Fusionar Atributo android:name
<receiver> Fusionar Atributo android:name
<screen> Fusionar Atributo android:screenSize
<service> Fusionar Atributo android:name
<supports-gl-texture> Fusionar Atributo android:name
<supports-screen> Fusionar Solo hay uno por <manifest>
<uses-configuration> Fusionar Solo hay uno por <manifest>
<uses-feature> Fusionar Atributo android:name (si no está presente, entonces el atributo android:glEsVersion)
<uses-library> Fusionar Atributo android:name
<uses-permission> Fusionar Atributo android:name
<uses-sdk> Fusionar Solo hay uno por <manifest>
Elementos personalizados Fusionar Sin coincidencia, son desconocidos para la herramienta de fusión, por lo que siempre se incluyen en el manifiesto fusionado.