Gérer les fichiers manifestes

Cette page décrit le processus de fusion des fichiers manifestes et explique comment appliquer des préférences de fusion afin de résoudre les conflits. Pour en savoir plus, consultez la présentation des fichiers manifestes d'application.

Fusionner plusieurs fichiers manifestes

Votre fichier APK ou Android App Bundle ne peut contenir qu'un seul fichier AndroidManifest.xml, contrairement à votre projet Android Studio qui peut contenir plusieurs fichiers manifestes fournis par l'ensemble de sources principal, les variantes de compilation et les bibliothèques importées. Lorsque vous compilez votre application, le build Gradle fusionne tous les fichiers manifestes en un seul fichier qui est empaqueté dans votre application.

L'outil de fusion des fichiers manifestes combine tous les éléments XML de chaque fichier en suivant une méthode heuristique de fusion et en respectant les préférences de fusion que vous avez définies avec des attributs XML spéciaux.

Conseil : Utilisez la vue Merged Manifest (Manifeste fusionné), décrit dans une section ci-dessous, pour afficher un aperçu des résultats du fichier manifeste fusionné et pour identifier les erreurs liées à des conflits.

Priorités de fusion

L'outil de fusion combine tous les fichiers manifestes en un seul fichier de manière séquentielle, en fonction de la priorité de chaque fichier. Par exemple, si vous disposez de trois fichiers manifestes, le moins prioritaire est fusionné avec le fichier suivant dans l'ordre de priorité, puis le fichier ainsi obtenu est lui-même fusionné avec le fichier au niveau de priorité le plus élevé, comme l'illustre la figure 1.

Figure 1 : Processus de fusion de trois fichiers manifestes, de la priorité la plus basse à la priorité la plus élevée

Trois types de fichiers manifestes peuvent être fusionnés, et leurs priorités de fusion sont les suivantes (en commençant par la priorité la plus élevée) :

  1. Fichier manifeste de votre variante de compilation

    Si vous disposez de plusieurs ensembles de sources pour votre variante, les priorités de leurs fichiers manifestes sont les suivantes :

    • Fichier manifeste de la variante de compilation (par exemple, src/demoDebug/)
    • Fichier manifeste du type de compilation (par exemple, src/debug/)
    • Fichier manifeste du type de produit (par exemple, src/demo/)

      Si vous utilisez des groupes de types, les priorités des fichiers manifestes correspondent à l'ordre dans lequel chaque dimension est répertoriée dans la propriété flavorDimensions (la première correspondant à la priorité la plus élevée).

  2. Fichier manifeste principal du module d'application
  3. Fichier manifeste d'une bibliothèque incluse

    Si vous disposez de plusieurs bibliothèques, les priorités de leurs fichiers manifestes correspondent à l'ordre dans lequel elles apparaissent dans votre bloc dependencies Gradle.

Par exemple, le fichier manifeste d'une bibliothèque est fusionné avec le fichier manifeste principal, puis le fichier manifeste principal est fusionné avec le fichier manifeste de la variante de compilation. Notez que ces priorités de fusion sont les mêmes pour tous les ensembles de sources, comme décrit dans la section Compiler avec des ensembles de sources.

Important : Les configurations de compilation du fichier build.gradle ignorent les attributs correspondants du fichier manifeste fusionné. Par exemple, l'attribut minSdk du fichier build.gradle ou build.gradle.kts ignore l'attribut correspondant dans l'élément <uses-sdk> du fichier manifeste. Pour éviter toute confusion, omettez l'élément <uses-sdk> et ne définissez ces propriétés que dans le fichier build.gradle. Pour en savoir plus, consultez Configurer votre build.

Heuristiques de conflits de fusion

L'outil de fusion peut établir une correspondance logique entre chaque élément XML d'un fichier manifeste et un élément correspondant d'un autre fichier manifeste. Pour en savoir plus sur le fonctionnement de la mise en correspondance, consultez les priorités de fusion dans la section précédente.

Si un élément du fichier manifeste de priorité inférieure ne correspond à aucun élément du fichier manifeste de priorité supérieure, il est ajouté au fichier manifeste fusionné. En revanche, s'il existe un élément correspondant, l'outil de fusion tente de combiner tous les attributs de chacun au sein du même élément. Si l'outil détecte que les deux fichiers manifestes contiennent le même attribut avec des valeurs différentes, un conflit de fusion se produit.

Le tableau 1 présente les résultats qui peuvent être obtenus lorsque l'outil de fusion tente de combiner tous les attributs au sein du même élément.

Tableau 1. Comportement de fusion par défaut pour les valeurs d'attribut

Attribut haute priorité Attribut basse priorité Résultat fusionné de l'attribut
Aucune valeur Aucune valeur Aucune valeur (utiliser la valeur par défaut)
Valeur B Valeur B
Valeur A Aucune valeur Valeur A
Valeur A Valeur A
Valeur B Erreur de conflit : vous devez ajouter un repère de règle de fusion.

Dans certains cas, l'outil de fusion peut toutefois se comporter différemment afin d'éviter les conflits de fusion :

  • Les attributs de l'élément <manifest> ne sont jamais fusionnés. Seuls les attributs du fichier manifeste présentant la priorité la plus élevée sont utilisés.
  • L'attribut android:required dans les éléments <uses-feature> et <uses-library> utilise une fusion OR. En cas de conflit, "true" est appliqué, et la fonctionnalité ou la bibliothèque requise par un fichier manifeste est toujours incluse.
  • Les attributs de l'élément <uses-sdk> utilisent toujours la valeur du fichier manifeste présentant la priorité la plus élevée, sauf dans les cas suivants :
    • Lorsque le fichier manifeste de priorité inférieure présente une valeur minSdk supérieure, une erreur se produit, sauf si vous appliquez la règle de fusion overrideLibrary.
    • Lorsque le fichier manifeste de priorité inférieure présente une valeur targetSdkVersion inférieure, l'outil de fusion utilise la valeur du fichier manifeste de priorité supérieure, mais il ajoute également toutes les autorisations système nécessaires pour que la bibliothèque importée continue de fonctionner correctement (dans les cas où la version supérieure d'Android impose des restrictions d'autorisation accrues). Pour en savoir plus sur ce comportement, consultez Autorisations système implicites.
  • L'élément <intent-filter> n'est jamais mis en correspondance entre les fichiers manifestes. Chacun est considéré comme unique et ajouté à l'élément parent commun dans le fichier manifeste fusionné.

Pour tous les autres conflits entre les attributs, vous recevez une erreur et vous devez indiquer à l'outil de fusion comment le résoudre en ajoutant un attribut spécial dans le fichier manifeste de priorité supérieure. Consultez la section suivante sur les repères de règle de fusion.

Évitez de dépendre des valeurs d'attribut par défaut. Comme tous les attributs uniques sont combinés dans le même élément, des résultats inattendus peuvent se produire si le fichier manifeste de priorité supérieure dépend de la valeur par défaut d'un attribut sans le déclarer. Par exemple, si le fichier manifeste de priorité supérieure ne déclare pas l'attribut android:launchMode, il utilise la valeur par défaut "standard", mais si le fichier manifeste de priorité inférieure déclare cet attribut avec une valeur différente, cette valeur est appliquée au fichier manifeste fusionné, ce qui remplace la valeur par défaut. Vous devez définir explicitement chaque attribut tel que vous le souhaitez. Les valeurs par défaut de chaque attribut sont présentées dans la documentation de référence sur les fichiers manifestes.

Repères de règle de fusion

Un repère de règle de fusion est un attribut XML que vous pouvez utiliser pour indiquer votre préférence concernant la résolution des conflits de fusion ou la suppression des éléments et attributs indésirables. Vous pouvez appliquer un repère à un élément entier ou à certains attributs d'un élément.

Lorsque vous fusionnez deux fichiers manifestes, l'outil de fusion recherche ces repères dans le fichier manifeste de priorité supérieure.

Tous les repères appartiennent à l'espace de noms Android tools. Vous devez donc commencer par déclarer cet espace de noms dans l'élément <manifest>, comme indiqué ci-dessous :

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

Repères de nœud

Pour appliquer une règle de fusion à un élément XML entier (à tous les attributs d'un élément de fichier manifeste donné et à toutes ses balises enfants), utilisez les attributs suivants :

tools:node="merge"
En l'absence de conflits, fusionne tous les attributs de cette balise et tous les éléments imbriqués à l'aide de la méthode heuristique de conflit de fusion. Il s'agit du comportement par défaut pour les éléments.

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<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"
Fusionne les attributs de cette balise uniquement ; ne fusionne pas les éléments imbriqués.

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
</activity>
tools:node="remove"
Supprime cet élément du fichier manifeste fusionné. Utilisé lorsque vous détectez un élément dont vous n'avez pas besoin dans votre fichier manifeste fusionné et que celui-ci a été fourni par un fichier manifeste de priorité inférieure sur lequel vous n'avez aucun contrôle (une bibliothèque importée, par exemple).

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity-alias android:name="com.example.alias">
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>
tools:node="removeAll"
Semblable à tools:node="remove", mais supprime tous les éléments correspondant à ce type d'élément (dans le même élément parent).

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity-alias android:name="com.example.alias">
</activity-alias>
tools:node="replace"
Remplace complètement l'élément de priorité inférieure. Autrement dit, s'il existe un élément correspondant dans le fichier manifeste de priorité inférieure, il est ignoré et cet élément est utilisé tel qu'il apparaît dans ce fichier manifeste.

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity-alias android:name="com.example.alias">
  <meta-data android:name="fox"
      android:value="@string/dingeringeding"/>
</activity-alias>
tools:node="strict"
Génère un échec de compilation chaque fois que cet élément du fichier manifeste de priorité inférieure ne correspond pas exactement à celui du fichier de priorité supérieure (sauf s'il est résolu par d'autres repères de règle de fusion). Remplace la méthode heuristique de conflit de fusion. Par exemple, si le fichier manifeste de priorité inférieure inclut un attribut supplémentaire, la compilation échoue (alors que le comportement par défaut ajoute l'attribut supplémentaire au fichier manifeste fusionné).

Fichier manifeste basse priorité :

<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>

Fichier manifeste haute priorité :

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

Cela entraîne une erreur de fusion des fichiers manifestes. Aucune différence n'est tolérée entre les éléments des deux fichiers manifestes. Vous devez appliquer d'autres repères de règle de fusion pour résoudre ces différences. (Sans tools:node="strict", ces deux fichiers peuvent fusionner sans erreur, comme illustré dans l'exemple correspondant à tools:node="merge".)

Repères d'attribut

Pour qu'une règle de fusion s'applique uniquement à certains attributs d'une balise de fichier manifeste, utilisez les attributs suivants. Chaque attribut accepte un ou plusieurs noms d'attribut (espace de noms d'attribut compris), séparés par une virgule.

tools:remove="attr, ..."
Supprime les attributs spécifiés du fichier manifeste fusionné. Utilisé lorsque le fichier manifeste de priorité inférieure inclut ces attributs et que vous souhaitez vous assurer qu'ils ne soient pas inclus dans le fichier manifeste fusionné.

Fichier manifeste basse priorité :

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

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait">
tools:replace="attr, ..."
Remplace les attributs spécifiés dans le fichier manifeste de priorité inférieure par ceux de ce fichier manifeste. En d'autres termes, conserve toujours les valeurs du fichier manifeste dont la priorité est la plus élevée.

Fichier manifeste basse priorité :

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

Fichier manifeste haute priorité :

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

Fichier manifeste fusionné :

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
tools:strict="attr, ..."
Génère un échec de compilation chaque fois que ces attributs du fichier manifeste de priorité inférieure ne correspondent pas exactement aux attributs du fichier manifeste de priorité supérieure. Il s'agit du comportement par défaut pour tous les attributs, à l'exception de ceux présentant des comportements spéciaux, comme décrit dans Heuristiques de conflits de fusion.

Fichier manifeste basse priorité :

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

Fichier manifeste haute priorité :

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

Cela entraîne une erreur de fusion des fichiers manifestes. Vous devez appliquer d'autres repères de règle de fusion pour résoudre le conflit. Il s'agit du comportement par défaut. Vous obtiendrez donc le même résultat en ajoutant explicitement tools:strict="screenOrientation".

Vous pouvez également appliquer plusieurs repères à un seul élément, comme illustré dans l'exemple suivant :

Fichier manifeste basse priorité :

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

Fichier manifeste haute priorité :

<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">

Fichier manifeste fusionné :

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

Sélecteur de repère

Si vous souhaitez seulement appliquer les repères de règle de fusion à une bibliothèque importée spécifique, ajoutez l'attribut tools:selector avec le nom de package de la bibliothèque.

Par exemple, avec le fichier manifeste suivant, la règle de fusion remove n'est appliquée que lorsque le fichier manifeste de priorité inférieure provient de la bibliothèque com.example.lib1 :

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

Si le fichier manifeste de priorité inférieure provient d'une autre source, la règle de fusion remove est ignorée.

Remarque : Si vous utilisez cet attribut avec l'un des repères d'attribut, il s'applique à tous les attributs spécifiés dans le repère.

Ignorer <uses-sdk> pour les bibliothèques importées

Par défaut, lorsque vous importez une bibliothèque dont la valeur minSdk est supérieure à celle du fichier manifeste principal, une erreur se produit et la bibliothèque ne peut pas être importée.

Pour que l'outil de fusion ignore ce conflit et importe la bibliothèque tout en conservant la valeur minSdk inférieure de votre application, ajoutez l'attribut overrideLibrary à la balise <uses-sdk>. La valeur de l'attribut peut être un ou plusieurs noms de package de bibliothèque (séparés par une virgule), indiquant les bibliothèques qui peuvent ignorer la valeur minSdk du fichier manifeste principal.

Par exemple, si le fichier manifeste principal de votre application applique overrideLibrary comme ceci :

<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"/>
...

Le fichier manifeste suivant peut être fusionné sans erreur concernant la balise <uses-sdk>, et le fichier manifeste fusionné conserve la valeur minSdk="2" du fichier manifeste de l'application.

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

Autorisations système implicites

Certaines API Android, qui étaient auparavant librement accessibles par les applications, ont été soumises à des autorisations système dans les versions récentes d'Android.

Pour éviter le dysfonctionnement des applications qui souhaitent accéder à ces API, les versions récentes d'Android permettent aux applications de continuer à accéder à ces API sans autorisation si targetSdkVersion est défini sur une valeur inférieure à la version dans laquelle la restriction a été ajoutée. Ce comportement accorde à l'application une autorisation implicite qui lui permet d'accéder aux API. Les fichiers manifestes fusionnés qui ont des valeurs différentes pour targetSdkVersion peuvent être affectés.

Si le fichier manifeste de priorité inférieure présente une valeur targetSdkVersion inférieure qui lui accorde une autorisation implicite, et que le fichier manifeste de priorité supérieure ne dispose pas de la même autorisation implicite (parce que sa valeur targetSdkVersion est supérieure ou égale à la version dans laquelle la restriction a été ajoutée), l'outil de fusion ajoute explicitement l'autorisation système au fichier manifeste fusionné.

Par exemple, si votre application définit targetSdkVersion sur 4 ou plus et importe une bibliothèque dont la valeur targetSdkVersion est définie sur 3 ou moins, l'outil de fusion ajoute l'autorisation WRITE_EXTERNAL_STORAGE au fichier manifeste fusionné.

Le tableau 2 présente toutes les autorisations qui peuvent être ajoutées au fichier manifeste fusionné.

Tableau 2. Liste des autorisations que l'outil de fusion peut ajouter au fichier manifeste fusionné

Déclaration du fichier manifeste de priorité inférieure Autorisations ajoutées au fichier manifeste fusionné
La valeur targetSdkVersion est inférieure ou égale à 3 WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
La valeur targetSdkVersion est inférieure ou égale à 15 et utilise READ_CONTACTS READ_CALL_LOG
La valeur targetSdkVersion est inférieure ou égale à 15 et utilise WRITE_CONTACTS WRITE_CALL_LOG

Inspecter le fichier manifeste fusionné et détecter les conflits

Avant même de compiler votre application, vous pouvez afficher un aperçu de votre fichier manifeste fusionné. Pour afficher un aperçu, procédez comme suit :

  1. Dans Android Studio, ouvrez le fichier AndroidManifest.xml.
  2. Cliquez sur l'onglet Merged Manifest (Manifeste fusionné) en bas de l'éditeur.

La vue "Merged Manifest" (Manifeste fusionné) présente les résultats du fichier manifeste fusionné à gauche et des informations sur chaque fichier manifeste fusionné à droite, comme le montre la figure 2.

À gauche, les éléments fusionnés à partir de fichiers manifestes de priorité inférieure sont mis en surbrillance dans différentes couleurs. La légende des différentes couleurs est spécifiée sous Manifest Sources (Sources du fichier manifeste).

Figure 2. Vue "Merged Manifest" (Manifeste fusionné)

Les fichiers manifestes qui faisaient partie du build, mais qui n'ont pas contribué aux éléments ou attributs sont présentés sous Other Manifest Files (Autres fichiers manifestes).

Pour connaître la provenance d'un élément, cliquez dessus dans le volet de gauche. Les détails apparaissent à droite, sous Merging Log (Journal de fusion).

En cas de conflits, ceux-ci apparaissent sous Merging Errors (Erreurs de fusion), avec une recommandation de résolution du conflit à l'aide des repères de règle de fusion.

Les erreurs sont également affichées dans la fenêtre Event Log (Journal des événements). Pour les afficher, sélectionnez View > Tool Windows > Event Log (Vue > Outils Windows > Journal des événements).

Pour afficher le journal complet de l'arbre de décision de fusion, vous trouverez le fichier journal dans le répertoire build/outputs/logs/ de votre module, sous le nom manifest-merger-buildVariant-report.txt.

Règles de fusion

L'outil de fusion des fichiers manifestes peut établir une correspondance logique entre chaque élément XML d'un fichier manifeste et un élément correspondant de l'autre fichier. Pour ce faire, il utilise une clé de correspondance : soit une valeur d'attribut unique (comme android:name), soit l'unicité naturelle de la balise proprement dite (par exemple, il ne peut y avoir qu'un seul élément <supports-screen>).

Si deux fichiers manifestes contiennent le même élément XML, l'outil fusionne les deux éléments à l'aide de l'une des trois règles de fusion suivantes :

Fusionner
Combine tous les attributs non conflictuels dans la même balise et fusionne les éléments enfants conformément à leur règle de fusion respective. Si des attributs sont en conflit, ceux-ci sont fusionnés à l'aide des repères de règles de fusion.
Fusionner les enfants uniquement
Ne combine et ne fusionne pas les attributs (conserve uniquement les attributs fournis par le fichier manifeste à la priorité la plus élevée), et fusionne les éléments enfants conformément à leur règle de fusion.
Keep
Laisse l'élément tel quel et l'ajoute à l'élément parent commun dans le fichier fusionné. Cette règle n'est utilisée que lorsqu'il peut y avoir plusieurs déclarations pour le même élément.

Le tableau 3 présente chaque type d'élément, le type de règle de fusion utilisé et la clé utilisée pour déterminer une correspondance d'éléments entre deux fichiers manifestes.

Tableau 3. Règles de fusion d'éléments de fichier de manifeste et clés de correspondance

Élément Règle de fusion Clé de correspondance
<action> Fusionner Attribut android:name
<activity> Fusionner Attribut android:name
<application> Fusionner Une seule par <manifest>
<category> Fusionner Attribut android:name
<data> Fusionner Une seule par <intent-filter>
<grant-uri-permission> Fusionner Une seule par <provider>
<instrumentation> Fusionner Attribut android:name
<intent-filter> Keep Aucune correspondance ; plusieurs déclarations au sein de l'élément parent sont autorisées
<manifest> Fusionner les enfants uniquement Une seule par fichier
<meta-data> Fusionner Attribut android:name
<path-permission> Fusionner Une seule par <provider>
<permission-group> Fusionner Attribut android:name
<permission> Fusionner Attribut android:name
<permission-tree> Fusionner Attribut android:name
<provider> Fusionner Attribut android:name
<receiver> Fusionner Attribut android:name
<screen> Fusionner Attribut android:screenSize
<service> Fusionner Attribut android:name
<supports-gl-texture> Fusionner Attribut android:name
<supports-screen> Fusionner Une seule par <manifest>
<uses-configuration> Fusionner Une seule par <manifest>
<uses-feature> Fusionner Attribut android:name (ou, à défaut, attribut android:glEsVersion)
<uses-library> Fusionner Attribut android:name
<uses-permission> Fusionner Attribut android:name
<uses-sdk> Fusionner Une seule par <manifest>
Éléments personnalisés Fusionner Aucune correspondance ; ces noms sont inconnus de l'outil de fusion et sont donc toujours inclus dans le fichier manifeste fusionné

Injecter des variables de build dans le fichier manifeste

Si vous devez insérer dans le fichier AndroidManifest.xml des variables définies dans le fichier build.gradle, vous pouvez utiliser la propriété manifestPlaceholders. Cette propriété utilise un mappage de paires clé/valeur, comme indiqué ci-dessous :

Groovy

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
    }
    ...
}

Kotlin

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
    }
    ...
}

Vous pouvez ensuite insérer un des espaces réservés dans le fichier manifeste en tant que valeur d'attribut :

<intent-filter ... >
    <data android:scheme="https" android:host="${hostName}" ... />
    ...
</intent-filter>

Par défaut, les outils de compilation fournissent également l'ID de votre application dans l'espace réservé ${applicationId}. Cette valeur correspond toujours à l'ID d'application final de la compilation actuelle, y compris les modifications apportées par les variantes de compilation. Cela peut s'avérer utile lorsque vous souhaitez utiliser un espace de noms unique pour des identifiants tels qu'une action d'intent, même entre vos variantes de compilation.

Par exemple, si votre fichier build.gradle se présente comme suit :

Groovy

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    flavorDimensions "type"
    productFlavors {
        free {
            applicationIdSuffix ".free"
            dimension "type"
        }
        pro {
            applicationIdSuffix ".pro"
            dimension "type"
        }
    }
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    flavorDimensions += "type"
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
            dimension = "type"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
            dimension = "type"
        }
    }
}

Vous pouvez insérer l'ID de l'application dans votre fichier manifeste comme ceci :

<intent-filter ... >
    <action android:name="${applicationId}.TRANSMOGRIFY" />
    ...
</intent-filter>

Résultat du fichier manifeste lorsque vous compilez le type de produit "libre" :

<intent-filter ... >
   <action android:name="com.example.myapp.free.TRANSMOGRIFY" />
    ...
</intent-filter>

Pour en savoir plus, consultez Définir l'ID d'application.