Changements de comportement dans Android 7.0

En plus de nouvelles fonctionnalités, Android 7.0 apporte plusieurs modifications au comportement du système et des API. Ce document met en évidence certains des principaux changements que vous devez comprendre et prendre en compte dans vos applications.

Si vous avez déjà publié une application pour Android, sachez qu'elle peut être affectée par ces modifications sur la plate-forme.

Batterie et mémoire

Android 7.0 apporte des modifications de comportement du système visant à améliorer l'autonomie de la batterie des appareils et à réduire l'utilisation de la RAM. Ces modifications peuvent affecter l'accès de votre application aux ressources système, ainsi que la manière dont elle interagit avec d'autres applications via certains intents implicites.

Sommeil

Introduit dans Android 6.0 (niveau d'API 23), la fonctionnalité Sommeil améliore l'autonomie de la batterie en reportant les activités du processeur et du réseau lorsqu'un utilisateur laisse un appareil débranché, immobile et avec l'écran éteint. Android 7.0 apporte des améliorations supplémentaires à la fonctionnalité Sommeil en appliquant un sous-ensemble de restrictions liées au processeur et au réseau lorsque l'appareil est débranché avec l'écran éteint, mais pas nécessairement lorsqu'il est en déplacement.

Illustration de la manière dont la fonctionnalité Sommeil applique un premier niveau de restrictions d'activité du système pour améliorer l'autonomie de la batterie

Figure 1 : Illustration de la manière dont la fonctionnalité Sommeil applique un premier niveau de restrictions d'activité du système pour améliorer l'autonomie de la batterie.

Lorsqu'un appareil est sur batterie et que l'écran est éteint pendant un certain temps, il passe en mode Sommeil et applique le premier sous-ensemble de restrictions: il désactive l'accès au réseau de l'application et reporte les tâches et les synchronisations. Si l'appareil est à l'arrêt pendant un certain temps après être passé à Sommeil, le système applique le reste des restrictions Sommeil aux alarmes PowerManager.WakeLock, AlarmManager, au GPS et aux recherches Wi-Fi. Que toutes les restrictions de la fonctionnalité Sommeil soient appliquées ou non, le système active l'appareil pour de brefs intervalles de maintenance, au cours desquels les applications sont autorisées à accéder au réseau et peuvent exécuter des tâches ou des synchronisations différées.

Illustration de la manière dont la fonctionnalité Sommeil applique un deuxième niveau de restrictions d'activité du système une fois que l'appareil est à l'arrêt pendant un certain temps

Figure 2. Illustration de la manière dont la fonctionnalité Sommeil applique un deuxième niveau de restrictions d'activité du système une fois que l'appareil est à l'arrêt pendant un certain temps.

Notez que si vous activez l'écran ou que vous connectez l'appareil, vous quittez la fonctionnalité Sommeil et supprimez ces restrictions de traitement. Ce comportement supplémentaire n'affecte pas les recommandations et les bonnes pratiques d'adaptation de votre application à la version précédente de la fonctionnalité Sommeil introduite dans Android 6.0 (niveau d'API 23), comme indiqué dans Optimiser les fonctionnalités Sommeil et Mise en veille des applications. Vous devez toujours suivre ces recommandations, par exemple utiliser Firebase Cloud Messaging (FCM) pour envoyer et recevoir des messages, et commencer à planifier les mises à jour pour vous adapter au comportement supplémentaire du mode Sommeil.

Project Svelte: optimisations en arrière-plan

Android 7.0 supprime trois diffusions implicites afin d'optimiser l'utilisation de la mémoire et la consommation d'énergie. Cette modification est nécessaire, car les annonces implicites lancent fréquemment des applications qui se sont inscrites pour les écouter en arrière-plan. Supprimer ces annonces peut grandement améliorer les performances de l'appareil et l'expérience utilisateur.

La connectivité des appareils mobiles change fréquemment, par exemple lors du passage du Wi-Fi aux données mobiles. Actuellement, les applications peuvent surveiller les changements de connectivité en enregistrant un récepteur pour la diffusion implicite CONNECTIVITY_ACTION dans leur fichier manifeste. Étant donné que de nombreuses applications s'inscrivent pour recevoir cette annonce, un seul commutateur réseau peut toutes les activer et traiter l'annonce en même temps.

De même, dans les versions précédentes d'Android, les applications pouvaient s'inscrire pour recevoir des diffusions ACTION_NEW_PICTURE et ACTION_NEW_VIDEO implicites d'autres applications, comme Appareil photo. Lorsqu'un utilisateur prend une photo avec l'application Appareil photo, ces applications s'activent pour traiter la diffusion.

Pour résoudre ces problèmes, Android 7.0 applique les optimisations suivantes:

  • Les applications ciblant Android version 7.0 (niveau 24 d'API) et ultérieures ne reçoivent pas les diffusions CONNECTIVITY_ACTION s'ils déclarent leur récepteur de diffusion dans le fichier manifeste. Les applications continueront à recevoir des diffusions CONNECTIVITY_ACTION si elles enregistrent leur BroadcastReceiver auprès de Context.registerReceiver() et que ce contexte est toujours valide.
  • Le système n'envoie plus d'annonces ACTION_NEW_PICTURE ou ACTION_NEW_VIDEO. Cette optimisation affecte toutes les applications, pas seulement celles qui ciblent Android 7.0.

Si votre application utilise l'un de ces intents, vous devez supprimer leurs dépendances dès que possible afin de pouvoir cibler correctement les appareils Android 7.0. Le framework Android fournit plusieurs solutions pour limiter le besoin de ces diffusions implicites. Par exemple, l'API JobScheduler fournit un mécanisme robuste pour planifier les opérations réseau lorsque les conditions spécifiées, telles que la connexion à un réseau illimité, sont remplies. Vous pouvez même utiliser JobScheduler pour réagir aux changements apportés aux fournisseurs de contenu.

Pour en savoir plus sur les optimisations en arrière-plan dans Android 7.0 (niveau d'API 24) et sur l'adaptation de votre application, consultez Optimisations en arrière-plan.

Modifications des autorisations

Android 7.0 apporte des modifications aux autorisations susceptibles d'affecter votre application.

Modifications des autorisations du système de fichiers

Afin de renforcer la sécurité des fichiers privés, l'accès au répertoire privé des applications ciblant Android 7.0 ou version ultérieure est restreint (0700). Ce paramètre empêche les fuites de métadonnées des fichiers privés, telles que leur taille ou leur existence. Ce changement d'autorisation a plusieurs effets secondaires:

  • Les autorisations d'accès aux fichiers privés ne doivent plus être assouplies par le propriétaire. Si vous tentez de le faire avec MODE_WORLD_READABLE et/ou MODE_WORLD_WRITEABLE, une SecurityException sera déclenchée.

    Remarque:À l'heure actuelle, cette restriction n'est pas entièrement appliquée. Les applications peuvent toujours modifier les autorisations d'accès à leur répertoire privé à l'aide d'API natives ou de l'API File. Toutefois, nous vous déconseillons vivement d'assouplir les autorisations au répertoire privé.

  • La transmission d'URI file:// en dehors du domaine du package risque de laisser le récepteur avec un chemin inaccessible. Par conséquent, les tentatives de transmission d'un URI file:// déclenchent une exception FileUriExposedException. La méthode recommandée pour partager le contenu d'un fichier privé consiste à utiliser FileProvider.
  • DownloadManager ne peut plus partager de fichiers stockés en mode privé par nom de fichier. Les anciennes applications peuvent se retrouver avec un chemin d'accès inaccessible lors de l'accès à COLUMN_LOCAL_FILENAME. Les applications ciblant Android 7.0 ou version ultérieure déclenchent une erreur SecurityException lorsqu'elles tentent d'accéder à COLUMN_LOCAL_FILENAME. Les anciennes applications qui définissent l'emplacement de téléchargement sur un emplacement public à l'aide de DownloadManager.Request.setDestinationInExternalFilesDir() ou DownloadManager.Request.setDestinationInExternalPublicDir() peuvent toujours accéder au chemin dans COLUMN_LOCAL_FILENAME. Toutefois, cette méthode est vivement déconseillée. Le moyen privilégié pour accéder à un fichier exposé par DownloadManager consiste à utiliser ContentResolver.openFileDescriptor().

Partager des fichiers entre des applications

Pour les applications ciblant Android 7.0, le framework Android applique la règle d'API StrictMode qui interdit d'exposer les URI file:// en dehors de votre application. Si un intent contenant un URI de fichier quitte votre application, celle-ci échoue avec une exception FileUriExposedException.

Pour partager des fichiers entre des applications, vous devez envoyer un URI content:// et accorder une autorisation d'accès temporaire à l'URI. Le moyen le plus simple d'accorder cette autorisation consiste à utiliser la classe FileProvider. Pour en savoir plus sur les autorisations et le partage de fichiers, consultez la section Partager des fichiers.

Améliorations liées à l'accessibilité

Android 7.0 inclut des modifications visant à améliorer la facilité d'utilisation de la plate-forme pour les utilisateurs malvoyants ou malvoyants. Ces modifications ne devraient généralement pas nécessiter de modifications du code de votre application. Toutefois, vous devez examiner ces fonctionnalités et les tester avec votre application afin d'évaluer les impacts potentiels sur l'expérience utilisateur.

Zoom sur l'écran

Android 7.0 permet aux utilisateurs de définir une taille d'affichage pour agrandir ou réduire tous les éléments à l'écran, améliorant ainsi l'accessibilité de l'appareil pour les personnes malvoyantes. Les utilisateurs ne peuvent pas zoomer sur l'écran au-delà d'une largeur minimale de sw320dp, qui correspond à la largeur d'un Nexus 4, un téléphone de taille moyenne courant.

Écran montrant la taille d'affichage sans zoom d'un appareil exécutant une image système Android 7.0
Écran montrant l'augmentation de la taille d'affichage d'un appareil exécutant une image système Android 7.0

Figure 3. L'écran de droite montre l'effet de l'augmentation de la taille d'affichage d'un appareil exécutant une image système Android 7.0.

Lorsque la densité de l'appareil change, le système envoie des notifications aux applications en cours d'exécution comme suit:

  • Si une application cible le niveau d'API 23 ou inférieur, le système ferme automatiquement tous ses processus en arrière-plan. Cela signifie que si un utilisateur quitte une application de ce type pour ouvrir l'écran Settings (Paramètres) et modifie le paramètre Display size (Taille d'affichage), le système ferme l'application comme s'il s'agissait d'une situation de mémoire insuffisante. Si l'application comporte des processus de premier plan, le système les informe de la modification de la configuration, comme décrit dans Gérer les modifications apportées à l'environnement d'exécution, comme si l'orientation de l'appareil avait changé.
  • Si une application cible Android 7.0, tous ses processus (au premier plan et en arrière-plan) sont informés de la modification de la configuration, comme décrit dans la section Gérer les modifications apportées à l'environnement d'exécution.

La plupart des applications n'ont pas besoin d'apporter de modifications pour prendre en charge cette fonctionnalité, à condition qu'elles respectent les bonnes pratiques Android. Points spécifiques à vérifier:

  • Testez votre application sur un appareil avec une largeur d'écran de sw320dp et assurez-vous qu'elle fonctionne correctement.
  • Lorsque la configuration de l'appareil change, mettez à jour les informations mises en cache qui dépendent de la densité, telles que les bitmaps mis en cache ou les ressources chargées à partir du réseau. Recherchez les modifications de configuration lorsque l'application reprend l'état "Mis en pause".

    Remarque:Si vous mettez en cache des données dépendantes de la configuration, il est recommandé d'inclure des métadonnées pertinentes, telles que la taille d'écran ou la densité de pixels appropriées pour ces données. L'enregistrement de ces métadonnées vous permet de décider si vous devez actualiser les données mises en cache après un changement de configuration.

  • Évitez de spécifier des dimensions en pixels, car elles ne s'adaptent pas à la densité de l'écran. Spécifiez plutôt les dimensions avec des unités de pixels indépendants de la densité (dp).

Paramètres Vision dans l'assistant de configuration

Android 7.0 inclut les paramètres Vision sur l'écran d'accueil, qui permet aux utilisateurs de configurer les paramètres d'accessibilité suivants sur un nouvel appareil : Geste d'agrandissement, Taille de police, Taille d'affichage et TalkBack. Cette modification augmente la visibilité des bugs liés aux différents paramètres d'écran. Pour évaluer l'impact de cette fonctionnalité, vous devez tester vos applications en activant ces paramètres. Vous trouverez les paramètres sous Paramètres > Accessibilité.

Association d'applications NDK à des bibliothèques de plate-forme

À partir d'Android 7.0, le système empêche les applications de s'associer de manière dynamique à des bibliothèques non NDK, ce qui peut entraîner le plantage de votre application. Ce changement de comportement vise à créer une expérience d'application cohérente entre les mises à jour de la plate-forme et les différents appareils. Même si votre code n'est pas associé à des bibliothèques privées, il est possible qu'une bibliothèque statique tierce dans votre application le fasse. Par conséquent, tous les développeurs doivent vérifier que leurs applications ne plantent pas sur les appareils équipés d'Android 7.0. Si votre application utilise du code natif, vous ne devez utiliser que des API NDK publiques.

Votre application peut tenter d'accéder aux API de la plate-forme privée de trois manières différentes:

  • Votre application accède directement aux bibliothèques de la plate-forme privée. Vous devez mettre à jour votre application pour inclure sa propre copie de ces bibliothèques ou utiliser les API NDK publiques.
  • Votre application utilise une bibliothèque tierce qui accède aux bibliothèques de plate-forme privées. Même si vous êtes certain que votre application n'accède pas directement aux bibliothèques privées, vous devez tout de même la tester pour ce scénario.
  • Votre application fait référence à une bibliothèque qui n'est pas incluse dans son APK. Par exemple, cela peut se produire si vous avez essayé d'utiliser votre propre copie d'OpenSSL, mais que vous avez oublié de l'associer au fichier APK de votre application. L'application peut s'exécuter normalement sur les versions de la plate-forme Android qui incluent libcrypto.so. Toutefois, l'application peut planter sur les versions ultérieures d'Android qui n'incluent pas cette bibliothèque (par exemple, Android 6.0 et versions ultérieures). Pour résoudre ce problème, veillez à regrouper toutes vos bibliothèques non NDK avec votre APK.

Les applications ne doivent pas utiliser de bibliothèques natives qui ne sont pas incluses dans le NDK, car elles peuvent être modifiées ou supprimées entre différentes versions d'Android. Le passage d'OpenSSL à BoringSSL en est un exemple. En outre, comme il n'existe aucune exigence de compatibilité pour les bibliothèques de plate-forme non incluses dans le NDK, différents appareils peuvent offrir différents niveaux de compatibilité.

Afin de réduire l'impact que cette restriction peut avoir sur les applications actuellement publiées, un ensemble de bibliothèques très utilisées (telles que libandroid_runtime.so, libcutils.so, libcrypto.so et libssl.so) est temporairement accessible sur Android 7.0 (niveau d'API 24) pour les applications ciblant le niveau d'API 23 ou inférieur. Si votre application charge l'une de ces bibliothèques, Logcat génère un avertissement et un toast s'affiche sur l'appareil cible pour vous avertir. Si ces avertissements s'affichent, vous devez mettre à jour votre application pour inclure sa propre copie de ces bibliothèques ou n'utiliser que les API NDK publiques. Les futures versions de la plate-forme Android sont susceptibles de restreindre complètement l'utilisation des bibliothèques privées et de provoquer le plantage de votre application.

Toutes les applications génèrent une erreur d'exécution lorsqu'elles appellent une API qui n'est ni publique ni accessible temporairement. Par conséquent, System.loadLibrary et dlopen(3) renvoient tous deux NULL, ce qui peut entraîner le plantage de votre application. Vous devez examiner le code de votre application pour supprimer l'utilisation d'API de plate-forme privée et tester vos applications de manière approfondie à l'aide d'un appareil ou d'un émulateur exécutant Android 7.0 (niveau d'API 24). Si vous ne savez pas si votre application utilise des bibliothèques privées, vous pouvez vérifier Logcat pour identifier l'erreur d'exécution.

Le tableau suivant décrit le comportement attendu d'une application en fonction de son utilisation de bibliothèques natives privées et de son niveau d'API cible (android:targetSdkVersion).

Bibliothèques Niveau d'API cible Accès à l'environnement d'exécution via l'éditeur de liens dynamique Comportement d'Android 7.0 (niveau d'API 24) Comportement futur de la plate-forme Android
NDK public Tout Accessibles Fonctionne comme prévu Fonctionne comme prévu
Privées (bibliothèques privées accessibles temporairement) 23 ou moins Temporairement accessible Fonctionne comme prévu, mais vous recevez un avertissement logcat. Erreur d'exécution
Privées (bibliothèques privées accessibles temporairement) 24 ou version ultérieure Limité Erreur d'exécution Erreur d'exécution
Privée (autre) Tout Limité Erreur d'exécution Erreur d'exécution

Vérifier si votre application utilise des bibliothèques privées

Pour vous aider à identifier les problèmes de chargement des bibliothèques privées, Logcat peut générer un avertissement ou une erreur d'exécution. Par exemple, si votre application cible le niveau d'API 23 ou inférieur et tente d'accéder à une bibliothèque privée sur un appareil équipé d'Android 7.0, un avertissement semblable au suivant peut s'afficher:

03-21 17:07:51.502 31234 31234 W linker  : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120

Ces avertissements Logcat vous indiquent quelle bibliothèque tente d'accéder à une API de plate-forme privée, sans provoquer le plantage de votre application. Toutefois, si l'application cible le niveau d'API 24 ou supérieur, Logcat génère l'erreur d'exécution suivante, ce qui peut entraîner le plantage de votre application:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
  at java.lang.Runtime.loadLibrary0(Runtime.java:977)
  at java.lang.System.loadLibrary(System.java:1602)

Vous pouvez également voir ces sorties logcat si votre application utilise des bibliothèques tierces qui créent un lien dynamique vers des API de plate-forme privée. L'outil readelf d'Android 7.0DK vous permet de générer une liste de toutes les bibliothèques partagées associées de manière dynamique à un fichier .so donné en exécutant la commande suivante:

aarch64-linux-android-readelf -dW libMyLibrary.so

Mettre à jour votre appli

Voici quelques étapes à suivre pour corriger ces types d'erreurs et vous assurer que votre application ne plante pas lors de futures mises à jour de la plate-forme:

  • Si votre application utilise des bibliothèques de plate-forme privées, vous devez la mettre à jour pour inclure sa propre copie de ces bibliothèques ou utiliser les API NDK publiques.
  • Si votre application utilise une bibliothèque tierce qui accède à des symboles privés, contactez l'auteur de la bibliothèque pour la mettre à jour.
  • Assurez-vous d'empaqueter toutes vos bibliothèques non NDK avec votre APK.
  • Utilisez les fonctions JNI standards au lieu de getJavaVM et getJNIEnv de libandroid_runtime.so :
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • Utilisez __system_property_get au lieu du symbole property_get privé de libcutils.so. Pour ce faire, utilisez __system_property_get avec les éléments suivants :
    #include <sys/system_properties.h>
    

    Remarque:La disponibilité et le contenu des propriétés système ne sont pas testés via CTS. Il est préférable d'éviter d'utiliser complètement ces propriétés.

  • Utilisez une version locale du symbole SSL_ctrl dans libcrypto.so. Par exemple, vous devez associer libcyrpto.a de manière statique dans votre fichier .so, ou inclure une version liée de manière dynamique de libcrypto.so depuis BoringSSL/OpenSSL et l'empaqueter dans votre APK.

Android for Work

Android 7.0 contient des modifications pour les applications ciblant Android for Work, y compris des modifications apportées à l'installation des certificats, à la réinitialisation des mots de passe, à la gestion secondaire des utilisateurs et à l'accès aux identifiants des appareils. Si vous créez des applications pour les environnements Android for Work, vous devez examiner ces modifications et modifier votre application en conséquence.

  • Vous devez installer un programme d'installation de certificat délégué avant que le DPC puisse le configurer. Pour les applications de profil et de propriétaire d'appareil ciblant Android 7.0 (niveau d'API 24), vous devez installer le programme d'installation de certificat délégué avant que l'outil de contrôle des règles relatives aux appareils (DPC) n'appelle DevicePolicyManager.setCertInstallerPackage(). Si le programme d'installation n'est pas déjà installé, le système génère une erreur IllegalArgumentException.
  • Les restrictions de réinitialisation de mot de passe pour les administrateurs d'appareils s'appliquent désormais aux propriétaires de profils. Les administrateurs de l'appareil ne peuvent plus utiliser DevicePolicyManager.resetPassword() pour effacer les mots de passe ni modifier ceux déjà définis. Les administrateurs de l'appareil peuvent toujours définir un mot de passe, mais uniquement lorsque l'appareil n'a pas de mot de passe, de code ni de schéma.
  • Les propriétaires de l'appareil et du profil peuvent gérer les comptes même si des restrictions sont définies. Les propriétaires d'appareils et de profils peuvent appeler les API Account Management même si des restrictions d'utilisateurs DISALLOW_MODIFY_ACCOUNTS sont en place.
  • Les propriétaires d'appareils peuvent gérer les utilisateurs secondaires plus facilement. Lorsqu'un appareil s'exécute en mode propriétaire de l'appareil, la restriction DISALLOW_ADD_USER est automatiquement définie. Cela empêche les utilisateurs de créer des utilisateurs secondaires non gérés. De plus, les méthodes CreateUser() et createAndInitializeUser() sont obsolètes et remplacées par la nouvelle méthode DevicePolicyManager.createAndManageUser().
  • Les propriétaires d'appareils peuvent accéder aux identifiants des appareils. Le propriétaire d'un appareil peut accéder à l'adresse MAC Wi-Fi d'un appareil à l'aide de DevicePolicyManager.getWifiMacAddress(). Si le Wi-Fi n'a jamais été activé sur l'appareil, cette méthode renvoie la valeur null.
  • Le paramètre "Mode Travail" contrôle l'accès aux applications professionnelles. Lorsque le mode Travail est désactivé, le lanceur d'applications du système indique que les applications professionnelles ne sont pas disponibles en les grisées. La réactivation du mode professionnel permet de rétablir le comportement normal.
  • Lors de l'installation d'un fichier PKCS #12 contenant une chaîne de certificats client et la clé privée correspondante à partir de l'interface utilisateur des paramètres, le certificat CA de la chaîne n'est plus installé dans le stockage des identifiants de confiance. Cela n'affecte pas le résultat de KeyChain.getCertificateChain() lorsque les applications tentent de récupérer la chaîne de certificats client ultérieurement. Si nécessaire, le certificat CA doit être installé séparément sur le stockage des identifiants de confiance via l'interface utilisateur des paramètres, avec un format encodé au format DER et avec l'extension de fichier .crt ou .cer.
  • À partir d'Android 7.0, l'enregistrement d'empreintes digitales et le stockage sont gérés par utilisateur. Si le DPC (Device Policy Client) d'un propriétaire de profil cible le niveau d'API 23 (ou inférieur) sur un appareil équipé d'Android 7.0 (niveau d'API 24), l'utilisateur peut toujours définir son empreinte digitale sur l'appareil, mais les applications professionnelles ne peuvent pas accéder à l'empreinte de l'appareil. Lorsque l'outil DPC cible le niveau d'API 24 ou supérieur, l'utilisateur peut définir l'empreinte digitale spécifiquement pour le profil professionnel en accédant à Paramètres > Sécurité > Sécurité du profil professionnel.
  • Un nouvel état de chiffrement ENCRYPTION_STATUS_ACTIVE_PER_USER est renvoyé par DevicePolicyManager.getStorageEncryptionStatus() pour indiquer que le chiffrement est actif et que la clé de chiffrement est liée à l'utilisateur. Le nouvel état n'est renvoyé que si l'outil DPC cible le niveau d'API 24 ou supérieur. Pour les applications ciblant des niveaux d'API antérieurs, ENCRYPTION_STATUS_ACTIVE est renvoyé, même si la clé de chiffrement est spécifique à l'utilisateur ou au profil.
  • Dans Android 7.0, plusieurs méthodes qui affectent généralement l'ensemble de l'appareil se comportent différemment si l'appareil dispose d'un profil professionnel installé avec un test professionnel distinct. Plutôt que d'affecter l'ensemble de l'appareil, ces méthodes ne s'appliquent qu'au profil professionnel. (La liste complète de ces méthodes est disponible dans la documentation DevicePolicyManager.getParentProfileInstance().) Par exemple, DevicePolicyManager.lockNow() verrouille uniquement le profil professionnel, au lieu de verrouiller l'ensemble de l'appareil. Pour chacune de ces méthodes, vous pouvez obtenir l'ancien comportement en appelant la méthode sur l'instance parente de DevicePolicyManager. Vous pouvez obtenir ce parent en appelant DevicePolicyManager.getParentProfileInstance(). Par exemple, si vous appelez la méthode lockNow() de l'instance parente, l'appareil entier est verrouillé.

Conservation des annotations

Android 7.0 corrige un bug qui empêchait la visibilité des annotations. Ce problème a permis à l'environnement d'exécution d'accéder aux annotations auxquelles il n'aurait pas dû accéder. Ces annotations comprenaient:

  • VISIBILITY_BUILD: destiné à être visible uniquement au moment de la compilation.
  • VISIBILITY_SYSTEM: destiné à être visible au moment de l'exécution, mais uniquement par le système sous-jacent.

Si votre application s'appuie sur ce comportement, veuillez ajouter une règle de conservation aux annotations qui doivent être disponibles au moment de l'exécution. Pour ce faire, utilisez @Retention(RetentionPolicy.RUNTIME).

Modifications de la configuration TLS/SSL par défaut

Android 7.0 apporte les modifications suivantes à la configuration TLS/SSL par défaut utilisée par les applications pour le trafic HTTPS et tout autre trafic TLS/SSL:

  • Les suites de chiffrement RC4 sont désormais désactivées.
  • Les suites de chiffrement CHACHA20-POLY1305 sont désormais activées.

La désactivation par défaut de RC4 peut entraîner une rupture de la connectivité HTTPS ou TLS/SSL lorsque le serveur ne négocie pas de suites de chiffrement modernes. La solution privilégiée consiste à améliorer la configuration du serveur afin d'utiliser des suites et des protocoles de chiffrement plus robustes et plus modernes. Idéalement, TLS v1.2 et AES-GCM doivent être activés, et les suites de chiffrement de sécurité persistant (ECDHE) doivent être activées et privilégiées.

Vous pouvez également modifier l'application afin d'utiliser un SSLSocketFactory personnalisé pour communiquer avec le serveur. La fabrique doit être conçue pour créer des instances SSLSocket dont certaines des suites de chiffrement requises par le serveur sont activées, en plus des suites de chiffrement par défaut.

Remarque:Ces modifications ne concernent pas WebView.

Applications ciblant Android 7.0

Ces modifications de comportement ne s'appliquent qu'aux applications qui ciblent Android 7.0 (niveau d'API 24) ou version ultérieure. Les applications qui se compilent pour Android 7.0, ou qui définissent targetSdkVersion sur Android 7.0 ou une version ultérieure doivent modifier leurs applications pour prendre en charge ces comportements, le cas échéant.

Modifications de sérialisation

Android 7.0 (niveau d'API 24) a corrigé un bug dans le calcul de l'identifiant serialVersionUID par défaut, qui ne correspondait pas à la spécification.

Les classes qui implémentent Serializable sans spécifier de champ serialVersionUID explicite peuvent voir une modification de leur serialVersionUID par défaut, ce qui entraînerait la génération d'une exception lors de la tentative de désérialisation des instances de la classe qui ont été sérialisées sur une version antérieure ou sérialisées par une application ciblant une version antérieure. Le message d'erreur ressemblera à ceci:

local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567

Pour résoudre ces problèmes, vous devez ajouter un champ serialVersionUID à toute classe concernée avec la valeur stream classdesc serialVersionUID du message d'erreur, par exemple 1234 dans le cas présent. Cette modification respecte toutes les bonnes pratiques recommandées pour l'écriture du code de sérialisation et fonctionnera sur toutes les versions d'Android.

Le bug spécifique qui a été corrigé était lié à la présence de méthodes d'initialisation statiques, à savoir <clinit>. Conformément à la spécification, la présence ou l'absence d'une méthode d'initialisation statique dans la classe affecte le serialVersionUID par défaut calculé pour cette classe. Avant la correction du bug, le calcul recherchait également un initialiseur statique dans la super-classe si une classe n'en possédait pas.

Pour être précis, ce changement n'affecte pas les applications qui ciblent les niveaux d'API 23 ou inférieurs, les classes comportant un champ serialVersionUID ou les classes comportant une méthode d'initialisation statique.

Autres points importants

  • Lorsqu'une application s'exécute sous Android 7.0, mais cible un niveau d'API inférieur, et que l'utilisateur modifie la taille d'affichage, le processus de l'application est arrêté. L'application doit pouvoir gérer ce scénario de manière optimale. Sinon, elle plante lorsque l'utilisateur la restaure à partir des éléments récents.

    Vous devez tester votre application pour vous assurer que ce comportement ne se produit pas. Pour ce faire, vous pouvez provoquer un plantage identique lors de la fermeture manuelle de l'application via DCM.

    Les applications ciblant Android 7.0 (niveau d'API 24) ou version ultérieure ne sont pas automatiquement supprimées en cas de changement de densité. Toutefois, elles peuvent toujours mal réagir aux changements de configuration.

  • Les applications sur Android 7.0 doivent pouvoir gérer correctement les modifications de configuration et ne doivent pas planter lors des démarrages suivants. Vous pouvez vérifier le comportement de l'application en modifiant la taille de la police (Paramètres > Affichage > Taille de police), puis en restaurant l'application à partir des éléments récents.
  • En raison d'un bug dans les versions précédentes d'Android, le système n'a pas signalé l'écriture sur un socket TCP sur le thread principal comme un cas de non-respect du mode strict. Android 7.0 corrige ce bug. Les applications qui présentent ce comportement génèrent désormais une android.os.NetworkOnMainThreadException. En règle générale, effectuer des opérations réseau sur le thread principal est déconseillé, car ces opérations ont généralement une latence élevée qui entraîne des erreurs ANR et des à-coups.
  • La famille de méthodes Debug.startMethodTracing() stocke désormais par défaut la sortie dans le répertoire spécifique au package sur un espace de stockage partagé, plutôt qu'au premier niveau de la carte SD. Cela signifie que les applications n'ont plus besoin de demander l'autorisation WRITE_EXTERNAL_STORAGE pour utiliser ces API.
  • De nombreuses API de plate-forme ont maintenant commencé à vérifier les charges utiles volumineuses envoyées dans les transactions Binder. Le système génère à nouveau TransactionTooLargeExceptions en RuntimeExceptions, au lieu de les enregistrer ou de les supprimer silencieusement. Un exemple courant consiste à stocker trop de données dans Activity.onSaveInstanceState(), ce qui entraîne la génération d'une RuntimeException par ActivityThread.StopInfo lorsque votre application cible Android 7.0.
  • Si une application publie des tâches Runnable dans un élément View et que l'élément View n'est pas associé à une fenêtre, le système met en file d'attente la tâche Runnable avec le View. La tâche Runnable ne s'exécute pas tant que l'élément View n'est pas associé à une fenêtre. Ce comportement corrige les bugs suivants :
    • Si une application est publiée dans un View à partir d'un thread autre que le thread UI de la fenêtre prévue, Runnable peut s'exécuter sur le mauvais thread.
    • Si la tâche Runnable a été publiée à partir d'un thread autre qu'un thread de looper, l'application peut exposer la tâche Runnable.
  • Si une application sur Android 7.0 disposant de l'autorisation DELETE_PACKAGES tente de supprimer un package, mais qu'une autre application l'a installé, le système exige la confirmation de l'utilisateur. Dans ce scénario, les applications doivent s'attendre à STATUS_PENDING_USER_ACTION comme état renvoyé lorsqu'elles appellent PackageInstaller.uninstall().
  • Le fournisseur JCA appelé Crypto est obsolète, car son seul algorithme, SHA1PRNG, est cryptographiquement faible. Les applications ne peuvent plus utiliser SHA1PRNG pour dériver des clés (de manière non sécurisée), car ce fournisseur n'est plus disponible. Pour en savoir plus, consultez l'article de blog Security "Crypto" provider completed in Android N.