Signification de « android:exported needs to be explicitly specified »

« Manifest merger failed: Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. » signifie que le manifeste final contient une activité, un service ou un récepteur de diffusion avec un filtre d’intent, mais sans paramètre d’accès explicite. Cette règle s’applique lorsque l’application cible Android 12/API 31 ou une version ultérieure.

Les messages équivalents concernant une balise <activity>, <service> ou <receiver> désignent le même problème. android:exported détermine si d’autres applications peuvent lancer ce composant. Ne définissez pas la valeur sur true uniquement pour réussir la compilation. Identifiez d’abord le composant exact et le manifeste source dans la sortie fusionnée. Consultez l’exigence officielle d’Android 12 concernant les composants exportés.

Ce guide se limite aux activités, services et récepteurs possédant des filtres d’intent. Les fournisseurs de contenu ne constituent pas une variante équivalente courante de cette erreur Android 12.

Identifier le composant défaillant et le manifeste auquel il appartient

Utilisez la sortie du fusionneur de manifestes avant de modifier le manifeste de votre application. L’entrée concernée peut provenir du module d’application, d’une variante de compilation, d’un module de test, d’un manifeste généré ou d’une dépendance tierce.

  1. Ouvrez le fichier AndroidManifest.xml du module concerné dans Android Studio.
  2. Sélectionnez Manifeste fusionné.
  3. Sélectionnez l’activité, le service ou le récepteur concerné.
  4. Utilisez Journal de fusion et Sources du manifeste pour identifier le manifeste qui le fournit.
  5. Si nécessaire, consultez le rapport de compilation du fusionneur de manifestes.
  6. Corrigez le manifeste propriétaire ou utilisez une règle de fusion ciblée de priorité supérieure uniquement lorsque ses conditions préalables sont remplies.

Résultat attendu : vous connaissez le type du composant, son nom et la source du manifeste responsable de l’attribut absent ou en conflit. Cette opération présente un faible risque et ne nécessite aucune annulation à l’exécution ; annulez uniquement une modification du manifeste si la validation ultérieure échoue. Android documente la vue fusionnée, les journaux, les sources, les rapports et les marqueurs de fusion dans sa documentation sur la gestion des fichiers manifestes.

Choisir la valeur correcte de android:exported

Pour un composant qui vous appartient ou que vous pouvez modifier, ajoutez une valeur explicite dans son manifeste propriétaire, puis recompilez la variante concernée et inspectez le manifeste fusionné final.

Rôle du composant Valeur appropriée Raison
Activité de lancement de l’application android:exported="true" Le lanceur est un point d’entrée externe de l’application.
Activité, service ou récepteur intentionnellement externe android:exported="true" À utiliser uniquement lorsqu’une autre application doit l’appeler.
Service interne uniquement android:exported="false" Empêche les accès externes inutiles.
Récepteur interne uniquement android:exported="false" Empêche les accès externes inutiles.
  1. Ouvrez le manifeste propriétaire du composant concerné.
  2. Ajoutez android:exported="true" uniquement si des applications externes doivent pouvoir l’atteindre.
  3. Ajoutez android:exported="false" s’il est réservé à un usage interne.
  4. Recompilez la variante concernée.
  5. Vérifiez que le manifeste fusionné final conserve la valeur examinée.

Risque : faible pour la modification du manifeste, mais définir la valeur sur true expose le composant aux accès externes. Les filtres d’intent ne constituent pas, à eux seuls, un contrôle d’accès suffisant pour un composant exposé. Examinez les implications de sécurité dans les recommandations Android relatives à android:exported. Pour annuler la modification, supprimez ou modifiez uniquement l’attribut ajouté, puis recompilez.

Corriger le cas de l’activité MAIN et LAUNCHER

Si l’activité concernée possède un filtre d’intent contenant MAIN et LAUNCHER, elle constitue le point d’entrée de l’application et doit normalement déclarer android:exported="true".

  1. Recherchez l’activité dont le filtre d’intent contient MAIN et LAUNCHER.
  2. Définissez android:exported="true" sur cette activité.
  3. Compilez l’application.
  4. Installez ou exécutez l’application et vérifiez que l’icône du lanceur ouvre l’activité prévue.

Résultat attendu : l’activité de lancement possède un état exporté explicite et reste accessible depuis le lanceur. Cette opération ne résout pas une erreur distincte qui désigne un service ou un récepteur. Le risque est faible ; restaurez la déclaration précédente uniquement si l’activité n’est plus un point d’entrée du lanceur.

Si le composant provient d’une dépendance, d’un module de test ou d’un manifeste généré

Si le manifeste fusionné indique qu’une autre entrée est propriétaire du composant, ne supposez pas que le manifeste principal de votre application est le bon endroit à modifier. Diagnostiquez la dépendance directe ou transitive, le module de test, la variante de compilation ou le manifeste généré qui apporte réellement le composant.

Option prudente : si la source semble obsolète, vérifiez si une mise à jour de dépendance compatible est disponible avant de maintenir une substitution locale. Une mise à jour peut supprimer ou corriger la déclaration, mais ce n’est pas garanti et cela doit être testé dans la variante concernée. Vérifiez que les fonctionnalités requises de la dépendance fonctionnent toujours et que le manifeste fusionné final contient la valeur prévue.

Ne supprimez pas un composant apporté par une dépendance uniquement pour faire disparaître l’erreur. Il peut être nécessaire à une fonctionnalité de bibliothèque.

Utiliser une substitution ciblée du fusionneur de manifestes uniquement si nécessaire

Utilisez une substitution uniquement après que le manifeste fusionné a prouvé qu’un manifeste de priorité inférieure définit le même composant et qu’il existe un véritable conflit sur l’attribut exported. La déclaration de priorité supérieure doit identifier le même composant avec android:name.

Remplacer une valeur exported vérifiée

  1. Déclarez l’espace de noms tools dans le manifeste de priorité supérieure.
  2. Déclarez le composant correspondant avec la valeur android:exported souhaitée.
  3. Utilisez tools:replace="android:exported" uniquement en cas de conflit réel sur cet attribut.
  4. Inspectez le manifeste fusionné pour confirmer le résultat.
  5. Recompilez et testez le chemin d’entrée prévu du composant.

Risque : moyen. Une substitution peut modifier l’accessibilité externe. Pour annuler, supprimez la déclaration de substitution du composant et tools:replace, puis recompilez.

Supprimer un composant de bibliothèque dont l’inutilité est établie

  1. Vérifiez que le composant n’est requis ni par la dépendance ni par une fonctionnalité de l’application.
  2. Ajoutez une déclaration de composant correspondante dans le manifeste de priorité supérieure.
  3. Appliquez tools:node="remove" à ce composant.
  4. Inspectez le manifeste fusionné pour confirmer la suppression.
  5. Compilez l’application et testez les fonctionnalités de la dépendance susceptibles d’utiliser le composant supprimé.

Risque : moyen. La suppression d’un composant peut perturber le comportement d’une bibliothèque. Pour annuler, supprimez la déclaration tools:node="remove" et recompilez.

Vérifier la correction dans le manifeste final et le comportement de l’application

  • Vérifiez que le manifeste fusionné affiche une valeur android:exported explicite et examinée sur le composant concerné.
  • Compilez correctement la variante concernée.
  • Testez le chemin d’entrée prévu : lanceur, lien profond, service ou comportement du récepteur, selon le cas.
  • Si l’entrée d’une dépendance a changé, testez les fonctionnalités de la dépendance qui peuvent appeler ce composant ou en dépendre.
  • Pour un composant accessible depuis l’extérieur, vérifiez manuellement si ses appelants nécessitent une protection par autorisation ou une validation de l’appelant en plus de l’état exported.

Une compilation réussie confirme que l’exigence de fusion est satisfaite ; elle ne prouve pas à elle seule que le composant est sécurisé ou se comporte comme prévu. Le partage d’URI de fichiers est un problème de contrôle d’accès distinct : suivez les recommandations pour partager des fichiers avec FileProvider au lieu d’exposer des URI de fichiers plutôt que d’exporter largement des composants. De même, les erreurs de stratégie de sécurité réseau Android sont distinctes de cet échec du fusionneur de manifestes.

Questions fréquentes

Dois-je définir android:exported=”true” pour corriger cette erreur ?

Non. Utilisez true uniquement lorsque d’autres applications doivent appeler le composant. Utilisez false pour les activités, services et récepteurs internes uniquement, puis vérifiez la sortie fusionnée.

Pourquoi l’erreur persiste-t-elle après avoir modifié mon activité de lancement ?

Le composant défaillant peut être une autre activité, un service ou un récepteur, ou provenir d’une dépendance, d’un module de test, d’une variante ou d’un manifeste généré. Consultez le manifeste fusionné et ses sources.

Puis-je utiliser tools:replace=”android:exported” ?

Uniquement lorsqu’un manifeste de priorité supérieure définit le même composant et qu’il existe un véritable conflit sur l’attribut exported. Inspectez le résultat fusionné final et testez le chemin d’entrée prévu du composant.