Restrictions concernant les interfaces non SDK

À partir d'Android 9 (niveau d'API 28), la plate-forme limite les interfaces non SDK que votre application peut utiliser. Ces restrictions s'appliquent chaque fois qu'une application fait référence à une interface non SDK ou tente d'obtenir son identifiant à l'aide de la réflexion ou de JNI. Ces restrictions ont été mises en place pour améliorer l'expérience utilisateur et celle des développeurs, et réduire les risques de déploiements d'urgence pour les développeurs et les risques de plantage pour les utilisateurs. Pour en savoir plus sur cette décision, consultez la page Amélioration de la stabilité en réduisant l'utilisation d'interfaces non SDK.

Faire la distinction entre les interfaces SDK et non SDK

De manière générale, les interfaces SDK publiques sont celles décrites dans l'index des packages du framework Android. La gestion des interfaces non SDK est un détail d'implémentation que l'API fait abstraction de ces interfaces. Ces interfaces peuvent donc être modifiées sans préavis.

Pour éviter les plantages et les comportements inattendus, les applications ne doivent utiliser que les parties de classe officiellement documentées dans le SDK. Cela signifie également que vous ne devez pas accéder à des méthodes ou à des champs qui ne figurent pas dans le SDK lorsque vous interagissez avec une classe à l'aide de mécanismes tels que la réflexion.

Listes d'API non SDK

À chaque version d'Android, des interfaces non SDK supplémentaires sont restreintes. Nous savons que ces restrictions peuvent avoir un impact sur le workflow de vos versions. C'est pourquoi nous voulons nous assurer que vous disposez des outils nécessaires pour détecter l'utilisation d'interfaces non SDK, que vous pouvez nous donner votre avis et que vous disposez d'assez de temps pour planifier les nouvelles règles et vous y adapter.

Pour minimiser l'impact des restrictions non SDK sur votre workflow de développement, les interfaces non SDK sont divisées en listes qui définissent le degré de restriction de leur utilisation, en fonction du niveau d'API ciblé. Le tableau suivant décrit chacune de ces listes:

Liste Tags de code Description
Liste de blocage
  • blocked
  • Obsolète: blacklist
Interfaces non SDK que vous ne pouvez pas utiliser quel que soit le niveau d'API cible de votre application. Si votre application tente d'accéder à l'une de ces interfaces, le système génère une erreur.
Bloquée de manière conditionnelle
  • max-target-x
  • Obsolète: greylist-max-x

À partir d'Android 9 (niveau d'API 28), chaque niveau d'API comporte des interfaces non SDK qui sont limitées lorsqu'une application cible ce niveau d'API.

Ces listes sont identifiées par le niveau d'API maximal (max-target-x) qu'une application peut cibler avant de ne plus pouvoir accéder aux interfaces non SDK de cette liste. Par exemple, une interface non SDK qui n'était pas bloquée sous Android Pie, mais qui est maintenant bloquée sous Android 10 fait partie de la liste max-target-p (greylist-max-p), où "p" signifie Pie ou Android 9 (niveau d'API 28).

Si votre application tente d'accéder à une interface restreinte pour votre niveau d'API cible, le système se comporte comme si l'API faisait partie de la liste de blocage.

Non compatible
  • unsupported
  • Abandonné: greylist
Interfaces non SDK qui ne sont pas restreintes et que votre application peut utiliser. Notez toutefois que ces interfaces ne sont pas prises en charge et peuvent être modifiées sans préavis. Attendez-vous à ce que ces interfaces soient bloquées de manière conditionnelle dans les futures versions d'Android dans une liste max-target-x.
SDK
  • public-api et sdk
  • Obsolète: public-api et whitelist
Interfaces pouvant être utilisées librement et désormais prises en charge dans l'index des packages du framework Android officiellement documenté.
Tester des API
  • test-api
Interfaces utilisées pour les tests internes des systèmes, telles que les API qui facilitent les tests via la suite de tests de compatibilité (CTS). Les API de test ne font pas partie du SDK. À partir d'Android 11 (niveau d'API 30), les API de test sont incluses dans la liste de blocage. Les applications ne sont donc pas autorisées à les utiliser, quel que soit leur niveau d'API cible. Toutes les API de test ne sont pas compatibles et peuvent être modifiées sans préavis, quel que soit le niveau d'API de la plate-forme.

Bien que vous puissiez utiliser certaines interfaces non SDK (en fonction du niveau d'API cible de votre application), l'utilisation d'un champ ou d'une méthode non SDK présente toujours un risque élevé d'endommager votre application. Si votre application repose sur des interfaces non SDK, vous devriez commencer à planifier une migration vers des interfaces SDK ou d'autres alternatives. Si vous ne trouvez pas d'alternative à l'utilisation d'une interface non SDK pour une fonctionnalité de votre application, vous devriez demander une nouvelle API publique.

Déterminer la liste à laquelle une interface appartient

Les listes d'interfaces non SDK sont créées dans le cadre de la plate-forme. Consultez les sections suivantes pour en savoir plus sur chaque version d'Android.

Android 15

Pour Android 15 (niveau d'API 35), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes:

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA-256 : 40134e205e58922a708c453726b279a296e6a1f34a988abd90cec0f3432ea5a9

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 15, consultez Mises à jour des restrictions d'interface non SDK dans Android 15.

Android 14

Pour Android 14 (niveau d'API 34), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes:

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA-256 : 7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 14, consultez Mises à jour des restrictions d'interface non SDK dans Android 14.

Android 13

Pour Android 13 (niveau d'API 33), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA-256 : 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 13, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 13, consultez Mises à jour des restrictions d'interface non SDK dans Android 13.

Android 12

Pour Android 12 (niveau d'API 31), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes:

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA256 : 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 12, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 12, consultez Modification des listes pour Android 12.

Android 11

Pour Android 11 (niveau d'API 30), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA-256 : a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 11, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 11, consultez Modification des listes pour Android 11.

Android 10

Pour Android 10 (niveau d'API 29), vous pouvez télécharger le fichier suivant, qui décrit toutes les interfaces non SDK, ainsi que les listes correspondantes :

Fichier : hiddenapi-flags.csv

Somme de contrôle SHA-256 : f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb

Pour en savoir plus sur les modifications apportées à la liste des API non SDK dans Android 10, y compris les suggestions d'alternatives dans les API publiques pour les API bloquées de manière conditionnelle dans Android 10, consultez Modification des listes pour Android 10.

Android 9

Pour Android 9 (niveau d'API 28), le fichier texte suivant contient la liste des API non SDK qui ne sont pas limitées (sur liste grise) : hiddenapi-light-greylist.txt.

La liste de blocage (blacklist) et la liste des API bloquées de manière conditionnelle (liste gris foncé) sont dérivées de ce fichier lors de la compilation.

Générer des listes à partir d'AOSP

Lorsque vous travaillez avec AOSP, vous pouvez générer un fichier hiddenapi-flags.csv contenant toutes les interfaces non SDK et les listes correspondantes. Pour ce faire, téléchargez la source AOSP, puis exécutez la commande suivante:

m out/soong/hiddenapi/hiddenapi-flags.csv

Vous trouverez alors le fichier à l'emplacement suivant :

out/soong/hiddenapi/hiddenapi-flags.csv

Comportement attendu lors de l'accès à des interfaces non SDK restreintes

Le tableau suivant décrit le comportement auquel vous pouvez vous attendre si votre application tente d'accéder à une interface non SDK faisant partie de la liste de blocage.

Moyens d'accès Résultat
Instruction Dalvik faisant référence à un champ NoSuchFieldError générée
Instruction Dalvik faisant référence à une méthode NoSuchMethodError générée
Réflexion à l'aide de Class.getDeclaredField() ou Class.getField() NoSuchFieldException générée
Réflexion à l'aide de Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException générée
Réflexion à l'aide de Class.getDeclaredFields(), Class.getFields() Les membres non SDK n'apparaissent pas dans les résultats
Réflexion à l'aide de Class.getDeclaredMethods(), Class.getMethods() Les membres non SDK n'apparaissent pas dans les résultats
JNI avec env->GetFieldID() NULL renvoyé, NoSuchFieldError générée
JNI avec env->GetMethodID() NULL renvoyé, NoSuchMethodError générée

Tester votre application pour les interfaces non SDK

Plusieurs méthodes existent pour tester des interfaces non SDK dans votre application.

Tester à l'aide d'une application débogable

Vous pouvez tester des interfaces non SDK en créant et en exécutant une application débogable sur un appareil ou un émulateur exécutant Android 9 (niveau d'API 28) ou version ultérieure. Assurez-vous que l'appareil ou l'émulateur que vous utilisez correspond au niveau d'API cible de votre application.

Lors des tests sur votre application, le système affiche un message de journal si votre application accède à certaines interfaces non SDK. Vous pouvez inspecter les messages de journal de votre application pour trouver les informations suivantes :

  • Classe, nom et type déclarants (au format utilisé par l'environnement d'exécution Android).
  • Moyen d'accès: par liens, via réflexion ou via JNI.
  • Liste à laquelle appartient l'interface non SDK.

Vous pouvez utiliser adb logcat pour accéder à ces messages de journal, qui apparaissent sous le PID de l'application en cours d'exécution. Par exemple, une entrée du journal peut se présenter comme suit :

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Test à l'aide de l'API StrictMode

Vous pouvez également tester la présence d'interfaces non SDK à l'aide de l'API StrictMode. Pour ce faire, utilisez la méthode detectNonSdkApiUsage. Après avoir activé l'API StrictMode, vous pouvez recevoir un rappel pour chaque utilisation d'une interface non SDK à l'aide d'un penaltyListener, dans lequel vous pouvez implémenter un traitement personnalisé. L'objet Violation fourni dans le rappel est dérivé de Throwable, et la trace de la pile jointe fournit le contexte de l'utilisation.

Test avec l'outil veridex

Vous pouvez également exécuter l'outil d'analyse statique veridex sur votre APK. L'outil veridex analyse l'intégralité du code base de l'APK, y compris les bibliothèques tierces, et signale toute utilisation d'interfaces non SDK détectée.

Les limites de l'outil veridex sont les suivantes :

  • Il ne peut pas détecter les appels via JNI.
  • Il ne peut détecter qu'un sous-ensemble d'appels par réflexion.
  • Son analyse des chemins de code inactifs est limitée aux vérifications au niveau de l'API.
  • Il ne peut être exécuté que sur des machines compatibles avec les instructions SSE4.2 et POPCNT.

Windows

Les binaires Windows natifs ne sont pas fournis, mais vous pouvez exécuter l'outil veridex sous Windows en exécutant les binaires Linux à l'aide du sous-système Windows pour Linux (WSL). Avant de suivre les étapes de cette section, installez le WSL et choisissez Ubuntu comme distribution Linux.

Une fois Ubuntu installé, lancez un terminal Ubuntu, puis procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt de composants prédéfinis de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, recherchez le fichier veridex-linux.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où your-app.apk est l'APK que vous souhaitez tester :

    ./appcompat.sh --dex-file=your-app.apk
    

macOS

Pour exécuter l'outil veridex sur macOS, procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt de versions précompilées de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, recherchez le fichier veridex-mac.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où /path-from-root/your-app.apk est le chemin d'accès à l'APK que vous souhaitez tester, en commençant par le répertoire racine de votre système:

    ./appcompat.sh --dex-file=/path-from-root/your-app.apk
    

Linux

Pour exécuter l'outil veridex sous Linux, procédez comme suit :

  1. Téléchargez l'outil veridex à partir du dépôt de versions précompilées de l'environnement d'exécution Android.
  2. Extrayez le contenu du fichier appcompat.tar.gz.
  3. Dans le dossier extrait, recherchez le fichier veridex-linux.zip et extrayez-le.
  4. Accédez au dossier décompressé, puis exécutez la commande suivante, où your-app.apk est l'APK que vous souhaitez tester :

    ./appcompat.sh --dex-file=your-app.apk
    

Test avec l'outil d'analyse lint d'Android Studio

Chaque fois que vous créez votre application dans Android Studio, l'outil Lint inspecte votre code pour détecter d'éventuels problèmes. Si votre application utilise des interfaces non SDK, des erreurs de compilation ou des avertissements peuvent s'afficher, selon la liste à laquelle ces interfaces appartiennent.

Vous pouvez également exécuter l'outil Lint à partir de la ligne de commande ou exécuter des inspections manuellement sur un projet, un dossier ou un fichier spécifique.

Test à l'aide de la Play Console

Lorsque vous importez votre application dans un canal de test dans la Play Console, elle est automatiquement testée afin de détecter d'éventuels problèmes. Un rapport pré-lancement est alors généré. Si votre application utilise des interfaces non SDK, une erreur ou un avertissement s'affiche dans le rapport pré-lancement, en fonction de la liste à laquelle ces interfaces appartiennent.

Pour en savoir plus, consultez la section sur la compatibilité Android dans Utiliser un rapport pré-lancement pour identifier les problèmes.

Demander une nouvelle API publique

Si vous ne trouvez pas d'alternative à l'utilisation d'une interface non SDK pour une fonctionnalité de votre application, vous pouvez demander une nouvelle API publique en créant une demande de fonctionnalité dans notre outil Issue Tracker.

Lorsque vous créez une demande de fonctionnalité, fournissez les informations suivantes:

  • L'API non compatible que vous utilisez, y compris le descripteur complet affiché dans le message Logcat Accessing hidden ....
  • La raison pour laquelle vous devez utiliser ces API, y compris des détails sur la fonctionnalité de haut niveau pour laquelle l'API est nécessaire, et pas seulement des détails de bas niveau.
  • La raison pour laquelle les API de SDK publiques associées ne suffisent pas à répondre à vos besoins.
  • Toutes les autres solutions que vous avez essayées et les raisons pour lesquelles elles n'ont pas fonctionné.

En fournissant ces informations dans votre demande de fonctionnalité, vous augmentez la probabilité que votre demande de nouvelle API publique soit acceptée.

Autres questions

Cette section inclut des réponses aux autres questions fréquemment posées par les développeurs :

Questions générales

Comment Google peut-il s'assurer de répondre aux besoins de toutes les applications via l'outil de Issue Tracker ?

Nous avons créé les listes initiales pour Android 9 (niveau d'API 28) à l'aide d'une analyse statique des applications, qui a été complétée à l'aide des méthodes suivantes :

  • Test manuel des principales applications Google Play et autres
  • Rapports internes
  • Collecte automatique des données auprès des utilisateurs internes
  • Rapports des previews développeur
  • Analyse statique supplémentaire conçue pour inclure de façon prudente plus de faux positifs

Lorsque nous évaluons les listes de chaque nouvelle version, nous prenons en compte l'utilisation de l'API ainsi que les commentaires des développeurs via l'outil Issue Tracker.

Comment puis-je activer l'accès aux interfaces non SDK ?

Vous pouvez activer l'accès aux interfaces non SDK sur des appareils de développement en modifiant la règle d'application des API à l'aide des commandes adb. Les commandes que vous utilisez varient en fonction du niveau de l'API. Ces commandes ne nécessitent pas d'appareil en mode root.

Android 10 (niveau d'API 29) ou version ultérieure

Pour activer l'accès, utilisez la commande adb suivante :

command:

adb shell settings put global hidden_api_policy  1

Pour réinitialiser les paramètres par défaut de la règle d'application des API, utilisez la commande suivante:

adb shell settings delete global hidden_api_policy
Android 9 (niveau d'API 28)

Pour activer l'accès, utilisez les commandes adb suivantes :

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

Pour rétablir les paramètres par défaut de la règle d'application des API, utilisez les commandes suivantes:

adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps

Vous pouvez définir l'entier dans la règle d'application des API sur l'une des valeurs suivantes :

  • 0 : Désactiver toute détection des interfaces non SDK. L'utilisation de ce paramètre désactive tous les messages de journal pour une utilisation d'interface non SDK, et vous empêche de tester votre application à l'aide de l'API StrictMode. Ce paramètre n'est pas recommandé.
  • 1 : Activer l'accès à toutes les interfaces non SDK, mais afficher des messages de journal contenant des avertissements pour toute utilisation d'interface non SDK. Ce paramètre vous permet également de tester votre application à l'aide de l'API StrictMode.
  • 2 : Interdire l'utilisation d'interfaces non SDK appartenant à la liste de blocage ou bloquées de manière conditionnelle pour votre niveau d'API cible.

Questions sur les listes d'interfaces non SDK

Où puis-je trouver les listes d'API non SDK dans l'image système ?

Elles sont encodées dans le champ et dans les bits d'indicateur d'accès à la méthode dans les fichiers dex de la plate-forme. L'image système ne contient pas de fichier distinct contenant ces listes.

Les listes des API non SDK sont-elles identiques sur différents appareils OEM avec les mêmes versions d'Android ?

Les appareils OEM peuvent ajouter leurs propres interfaces à la liste de blocage (liste noire), mais ne peuvent pas supprimer d'interfaces des listes d'API non SDK d'AOSP. Le CDD empêche ces modifications et les tests CTS garantissent qu'Android Runtime applique la liste.

Existe-t-il des restrictions pour les interfaces non NDK en code natif ?

Le SDK Android inclut des interfaces Java. La plate-forme a commencé à restreindre l'accès aux interfaces non SDK pour le code C/C++ natif dans Android 7 (niveau d'API 26). Pour en savoir plus, consultez Improving Stability with Private C/C++ Symbol Restrictions in Android N (Améliorer la stabilité avec les restrictions de symboles C/C++ privées dans Android N).

Est-il possible de limiter la manipulation des fichiers dex2oat ou DEX ?

Nous n'avons pas l'intention de restreindre l'accès au binaire dex2oat, mais nous ne prévoyons pas que le format de fichier DEX soit stable ou qu'il s'agisse d'une interface publique au-delà des parties publiquement spécifiées dans le format Dalvik Executable. Nous nous réservons le droit de modifier ou d'éliminer dex2oat et les parties non spécifiées du format DEX à tout moment. Notez également que les fichiers dérivés produits par dex2oat tels que ODEX (également appelé OAT), VDEX et CDEX sont tous des formats non spécifiés.

Que se passe-t-il si un SDK tiers essentiel (par exemple, un offuscateur) ne peut pas éviter d'utiliser des interfaces non SDK, mais s'engage à maintenir la compatibilité avec les futures versions d'Android ? Dans ce cas, Android peut-il renoncer à ses exigences de compatibilité ?

Nous ne prévoyons pas de renoncer aux exigences de compatibilité pour chaque SDK. Si un développeur de SDK ne peut maintenir la compatibilité qu'en fonction des interfaces figurant dans les listes non compatibles (anciennement grisées), il doit commencer à planifier une migration vers des interfaces SDK ou d'autres alternatives, et demander une nouvelle API publique chaque fois qu'il ne trouve pas d'alternative à l'utilisation d'une interface non SDK.

Les restrictions d'interface non SDK s'appliquent-elles à toutes les applications, y compris les applications système et propriétaires, et pas seulement aux applications tierces ?

Oui. Toutefois, les applications signées avec la clé de plate-forme et certaines applications d'image système sont exemptées. Notez que ces exceptions ne s'appliquent qu'aux applications qui font partie de l'image système (ou aux applications qui font partie de l'image système et qui ont été mises à jour). La liste est destinée uniquement aux applications compilées avec les API de la plate-forme privée, et non avec les API du SDK (c'est-à-dire LOCAL_PRIVATE_PLATFORM_APIS := true).