Comme les versions précédentes, Android 15 inclut des modifications de comportement susceptibles d'affecter votre application. Les modifications de comportement suivantes ne s'appliquent qu'aux applications ciblant Android 15 ou version ultérieure. Si votre application cible Android 15 ou une version ultérieure, vous devez modifier votre application pour prendre en charge ces comportements correctement, applicables.
N'oubliez pas de consulter également la liste des modifications de comportement qui affectent toutes les applications
fonctionnant sous Android 15, quelle que soit la targetSdkVersion
de votre application.
Fonctionnalité de base
Android 15 modifie ou étend diverses fonctionnalités de base du système Android.
Modifications apportées aux services de premier plan
Nous apportons les modifications suivantes aux services de premier plan avec Android 15.
- Comportement du délai avant expiration du service de premier plan de synchronisation des données
- Nouveau type de service de premier plan pour le traitement multimédia
- Restrictions concernant les broadcast receivers
BOOT_COMPLETED
qui lancent des services de premier plan - Restrictions concernant le démarrage des services de premier plan lorsqu'une application détient l'autorisation
SYSTEM_ALERT_WINDOW
Comportement du délai avant expiration du service de synchronisation des données de premier plan
Android 15 introduit un nouveau comportement de délai d'inactivité dans dataSync
pour le ciblage des applications
Android 15 (niveau d'API 35) ou version ultérieure Ce comportement s'applique également
Type de service de premier plan mediaProcessing
.
Le système autorise les services dataSync
d'une application à s'exécuter pendant six heures au total
dans une période de 24 heures, après quoi le système appelle
Méthode Service.onTimeout(int, int)
(introduite dans Android)
15). Pour l'instant, le service dispose de quelques secondes pour appeler
Service.stopSelf()
Lorsque Service.onTimeout()
est appelé, le
n'est plus considéré comme un service de premier plan. Si ce n'est pas le cas,
appelez Service.stopSelf()
, le système génère une exception interne. La
est consignée dans Logcat avec le message suivant:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
Pour éviter tout problème lié à ce changement de comportement, vous pouvez effectuer une ou plusieurs des suivantes:
- Demandez à votre service d'implémenter la nouvelle méthode
Service.onTimeout(int, int)
. Lorsque votre application reçoit le rappel, veillez à appelerstopSelf()
dans un en quelques secondes. Si vous n'arrêtez pas l'application immédiatement, le système génère un d'échec.) - Assurez-vous que les services
dataSync
de votre appli ne s'exécutent pas pendant plus de 6 heures par période de 24 heures (sauf si l'utilisateur interagit avec l'application, en réinitialisant le minuteur). - Démarrer uniquement les services de premier plan
dataSync
à la suite d'un utilisateur direct d'interaction ; puisque votre application est exécutée au premier plan lorsque le service démarre, votre service dispose des six heures complètes après la mise en arrière-plan de l'application. - Au lieu d'utiliser un service de premier plan
dataSync
, utilisez un API alternative.
Si les dataSync
services de premier plan de votre appli ont été exécutés pendant six heures au cours des dernières
24, vous ne pouvez pas démarrer un autre service de premier plan dataSync
à moins que l'utilisateur
a mis votre application au premier plan (ce qui réinitialise le minuteur). Si vous essayez de
démarrer un autre service de premier plan dataSync
, le système génère
ForegroundServiceStartNotAllowedException
avec un message d'erreur du type : "Time limit already exceeded pour le service de premier plan"
"dataSync".
Tests
Pour tester le comportement de votre application, vous pouvez activer des délais avant expiration de la synchronisation des données même si votre application
ne cible pas Android 15 (tant que l'application est exécutée sur un appareil Android 15)
appareil). Pour activer les délais avant expiration, exécutez la commande adb
suivante:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Vous pouvez également ajuster ce délai pour tester plus facilement
l'application se comporte lorsque la limite est atteinte. Pour définir un nouveau délai d'expiration, exécutez la
la commande adb
suivante:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
Nouveau type de service de premier plan pour le traitement multimédia
Android 15 introduit un nouveau type de service de premier plan : mediaProcessing
. Ce
est adapté à des opérations telles que le transcodage de fichiers multimédias. Pour
Par exemple, une application multimédia peut télécharger un fichier audio et doit le convertir en
format différent avant de le lire. Vous pouvez utiliser un premier plan mediaProcessing
pour s'assurer que la conversion se poursuit même lorsque l'application est dans
en arrière-plan.
Le système autorise les services mediaProcessing
d'une application à s'exécuter pendant six
toutes les 24 heures, au terme desquelles le système appelle le service
Méthode Service.onTimeout(int, int)
(introduite dans Android)
15). Pour l'instant, le service dispose de quelques secondes pour appeler
Service.stopSelf()
Si ce n'est pas le cas,
appelez Service.stopSelf()
, le système génère une exception interne. La
est consignée dans Logcat avec le message suivant:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
Pour éviter l'exception, vous pouvez effectuer l'une des opérations suivantes:
- Demandez à votre service d'implémenter la nouvelle méthode
Service.onTimeout(int, int)
. Lorsque votre application reçoit le rappel, veillez à appelerstopSelf()
dans un en quelques secondes. Si vous n'arrêtez pas l'application immédiatement, le système génère un d'échec.) - Assurez-vous que les services
mediaProcessing
de votre application ne s'exécutent pas pendant plus d'un total de 6 heures par période de 24 heures (sauf si l'utilisateur interagit avec l'application, en réinitialisant le minuteur). - Démarrer uniquement les services de premier plan
mediaProcessing
à la suite d'un utilisateur direct d'interaction ; puisque votre application est exécutée au premier plan lorsque le service démarre, votre service dispose des six heures complètes après la mise en arrière-plan de l'application. - Au lieu d'utiliser un service de premier plan
mediaProcessing
, utilisez une alternative API, comme WorkManager.
Si les services de premier plan mediaProcessing
de votre application sont exécutés pendant six heures dans le
24 dernières, vous ne pouvez pas démarrer un autre service de premier plan mediaProcessing
, sauf
l'utilisateur a mis votre application au premier plan (ce qui réinitialise le minuteur). Si vous
essayez de démarrer un autre service de premier plan mediaProcessing
, le système génère
ForegroundServiceStartNotAllowedException
avec un message d'erreur du type : "Time limit already exceeded pour le service de premier plan"
"mediaProcessing".
Pour plus d'informations sur le type de service mediaProcessing
, consultez la section Modifications
types de services de premier plan pour Android 15: Traitement multimédia
Tests
Pour tester le comportement de votre application, vous pouvez activer les délais avant expiration du traitement multimédia, même si
Votre application ne cible pas Android 15 (tant qu'elle est exécutée sur un
appareil Android 15). Pour activer les délais avant expiration, exécutez la commande adb
suivante:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Vous pouvez également ajuster ce délai pour tester plus facilement
l'application se comporte lorsque la limite est atteinte. Pour définir un nouveau délai d'expiration, exécutez la
la commande adb
suivante:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
Restrictions concernant les broadcast receivers BOOT_COMPLETED
qui lancent des services de premier plan
De nouvelles restrictions s'appliquent au lancement de BOOT_COMPLETED
broadcast receivers
services de premier plan. Les broadcast receivers BOOT_COMPLETED
ne sont pas autorisés à lancer les types de services de premier plan suivants :
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(cette restriction est en place pour le pays suivant :microphone
) Android 14)
Si un récepteur BOOT_COMPLETED
tente de lancer l'un de ces types de premier plan
le système génère ForegroundServiceStartNotAllowedException
.
Tests
Pour tester le comportement de votre application, vous pouvez activer ces nouvelles restrictions même si votre
L'application ne cible pas Android 15 (tant qu'elle est exécutée sur un appareil équipé d'Android 15).
appareil). Exécutez la commande adb
suivante:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
Pour envoyer une diffusion BOOT_COMPLETED
sans redémarrer l'appareil :
exécutez la commande adb
suivante:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Restrictions concernant le démarrage des services de premier plan lorsqu'une application détient l'autorisation SYSTEM_ALERT_WINDOW
Auparavant, si une application détenait l'autorisation SYSTEM_ALERT_WINDOW
, elle pouvait se lancer.
un service de premier plan même si l'application était exécutée en arrière-plan (comme
comme indiqué dans la section Exceptions des restrictions de démarrage en arrière-plan.
Si une application cible Android 15, cette exception est désormais plus restrictive. L'application doit désormais
disposer de l'autorisation SYSTEM_ALERT_WINDOW
et également avoir une superposition visible
fenêtre. Autrement dit, l'application doit d'abord lancer
Fenêtre TYPE_APPLICATION_OVERLAY
et fenêtre
doit être visible avant de démarrer
un service de premier plan.
Si votre application tente de démarrer un service de premier plan en arrière-plan sans
à ces nouvelles exigences (et qu'il ne fait l'objet d'aucune autre exemption), le
système génère ForegroundServiceStartNotAllowedException
.
Si votre application déclare l'autorisation SYSTEM_ALERT_WINDOW
et lance les services de premier plan en arrière-plan, il peut être affecté
le changement. Si votre application reçoit une ForegroundServiceStartNotAllowedException
, vérifiez
l'ordre des opérations de votre application et vous assurer que celle-ci dispose déjà d'un
fenêtre de superposition avant de tenter de démarrer un service de premier plan à partir de
en arrière-plan. Vous pouvez vérifier si la fenêtre en superposition est actuellement visible
en appelant View.getWindowVisibility()
, ou
peut ignorer View.onWindowVisibilityChanged()
pour recevoir une notification dès que la visibilité change.
Tests
Pour tester le comportement de votre application, vous pouvez activer ces nouvelles restrictions même si votre
L'application ne cible pas Android 15 (tant qu'elle est exécutée sur un appareil équipé d'Android 15).
appareil). Pour activer ces nouvelles restrictions sur le démarrage des services de premier plan :
en arrière-plan, exécutez la commande adb
suivante:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Modifications concernant les cas dans lesquels les applications peuvent modifier l'état général du mode Ne pas déranger
Les applications qui ciblent Android 15 ne peuvent plus modifier l'état ni la règle globaux du mode Ne pas déranger sur un appareil (en modifiant les paramètres utilisateur ou en désactivant le mode Ne pas déranger). À la place, les applications doivent contribuer à un AutomaticZenRule
, que le système combine dans une règle globale avec le schéma "most-restrictive-policy-wins" existant. Les appels d'API existantes qui ont précédemment affecté l'état global (setInterruptionFilter
, setNotificationPolicy
) entraînent la création ou la mise à jour d'un AutomaticZenRule
implicite, qui est activé ou désactivé en fonction du cycle d'appel de ces appels d'API.
Notez que cette modification n'affecte le comportement observable que si l'application appelle setInterruptionFilter(INTERRUPTION_FILTER_ALL)
et s'attend à ce que cet appel désactive un AutomaticZenRule
précédemment activé par ses propriétaires.
Modifications apportées à l'API OpenJDK
Android 15 poursuit le travail d'actualisation des bibliothèques principales d'Android pour aligner avec les fonctionnalités des dernières versions d'OpenJDK LTS.
Certaines de ces modifications peuvent affecter la compatibilité des applications pour le ciblage des applications Android 15 (niveau d'API 35):
Modifications apportées aux API de mise en forme des chaînes: validation de l'index d'arguments, des options la largeur et la précision sont désormais plus strictes lorsque vous utilisez API
String.format()
etFormatter.format()
:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
Par exemple, l'exception suivante est levée lorsqu'un index d'argument de 0 est utilisée (
%0
dans la chaîne de format):IllegalFormatArgumentIndexException: Illegal format argument index = 0
Dans ce cas, le problème peut être résolu en utilisant un index d'argument de 1 (
%1
). dans la chaîne de format).Modifications du type de composant de
Arrays.asList(...).toArray()
: lors de l'utilisationArrays.asList(...).toArray()
, le type de composant du tableau obtenu est Il s'agit maintenant d'une propriétéObject
, et non sur le type des éléments du tableau sous-jacent. Ainsi, le code suivant génère une exceptionClassCastException
:String[] elements = (String[]) Arrays.asList("one", "two").toArray();
Dans ce cas, pour conserver
String
comme type de composant dans le résultat vous pouvez utiliserCollection.toArray(Object[])
à la place:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Modifications apportées à la gestion du code de langue: lorsque vous utilisez l'API
Locale
, codes de langue pour l'hébreu, le yiddish et l'indonésien ne sont plus convertis et leur format obsolète (hébreu:iw
, yiddish:ji
et indonésien:in
). Lorsque vous spécifiez le code de langue pour l'un de ces paramètres régionaux, utilisez les codes ISO 639-1 (hébreu:he
, yiddish:yi
et indonésien:id
).Modifications apportées aux séquences int aléatoires: suite aux modifications apportées dans https://bugs.openjdk.org/browse/JDK-8301574, les éléments suivants : Les méthodes
Random.ints()
renvoient désormais une séquence de nombres différente de celle les méthodesRandom.nextInt()
:En règle générale, cette modification ne devrait pas entraîner de perturbations dans l'application, mais votre le code ne doit pas s'attendre à ce que la séquence générée à partir des méthodes
Random.ints()
correspond àRandom.nextInt()
.
La nouvelle API SequencedCollection
peut affecter la compatibilité de votre application
après avoir mis à jour compileSdk
dans la configuration de compilation de votre application pour utiliser
Android 15 (niveau d'API 35):
Collision avec
MutableList.removeFirst()
et Fonctions d'extensionMutableList.removeLast()
danskotlin-stdlib
Le type
List
en Java est mappé au typeMutableList
en Kotlin. Étant donné que les APIList.removeFirst()
etList.removeLast()
ont été introduits dans Android 15 (niveau d'API 35), le compilateur Kotlin résout les appels de fonction, par exemplelist.removeFirst()
, de manière statique en nouvelles APIList
au lieu des fonctions d'extensionkotlin-stdlib
Si une application est recompilée avec
compileSdk
défini sur35
etminSdk
défini sur34
ou version antérieure, puis que l'application s'exécute sur Android 14 ou version antérieure, un environnement d'exécution est générée:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;
L'option lint
NewApi
existante dans le plug-in Android Gradle peut les intercepter de nouvelles utilisations d'API../gradlew lint
MainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()Pour corriger les exceptions d'exécution et les erreurs lint,
removeFirst()
et Les appels de fonctionremoveLast()
peuvent être remplacés parremoveAt(0)
etremoveAt(list.lastIndex)
respectivement en Kotlin. Si vous utilisez Android Studio Ladybug | 2024.1.3 ou version ultérieure, il offre également une solution rapide pour ces erreurs.Envisagez de supprimer
@SuppressLint("NewApi")
etlintOptions { disable 'NewApi' }
si l'option lint a été désactivée.Collision avec d'autres méthodes dans Java
De nouvelles méthodes ont été ajoutées aux types existants, par exemple,
List
etDeque
. Ces nouvelles méthodes peuvent ne pas être compatibles avec les méthodes ayant les mêmes noms et types d'arguments dans d'autres interfaces et les cours. En cas de collision de signature de méthode avec incompatibilité, le compilateurjavac
génère une erreur au moment de la compilation. Exemple :Exemple d'erreur 1:
javac MyList.java
MyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface ListExemple d'erreur 2:
javac MyList.java
MyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorExemple d'erreur 3:
javac MyList.java
MyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorPour corriger ces erreurs de compilation, la classe mettant en œuvre ces interfaces doit remplacez la méthode par un type renvoyé compatible. Exemple :
@Override public Object getFirst() { return List.super.getLast(); }
Sécurité
Android 15 inclut des modifications qui renforcent la sécurité du système afin de protéger les applications et les utilisateurs des applications malveillantes.
Lancement de l'activité en arrière-plan sécurisée
Android 15 protège les utilisateurs des applications malveillantes et leur donne plus de contrôle sur leurs appareils en ajoutant des modifications qui empêchent les applications malveillantes en arrière-plan le fait de placer d'autres applications au premier plan, d'élever leurs privilèges et d'abuser l'interaction de l'utilisateur. Le lancement des activités en arrière-plan est limité depuis Android 10 (niveau d'API 29).
Empêcher les applications qui ne correspondent pas à l'UID supérieur de la pile de lancer des activités
Des applications malveillantes peuvent lancer l'activité d'une autre application au cours de la même tâche, puis
se superposent, créant ainsi l'illusion d'être cette application. Cette « tâche
détournement de contenu" contourne les restrictions de lancement actuelles en arrière-plan,
se produit dans la même
tâche visible. Pour atténuer ce risque, Android 15 ajoute
indicateur qui empêche le lancement des applications ne correspondant pas à l'UID supérieur de la pile
activités. Pour activer toutes les activités de votre application, mettez à jour le
allowCrossUidActivitySwitchFromBelow
dans le fichier AndroidManifest.xml
de votre application:
<application android:allowCrossUidActivitySwitchFromBelow="false" >
Les nouvelles mesures de sécurité sont actives si toutes les conditions suivantes sont remplies:
- L'application effectuant le lancement cible Android 15.
- L'application située au-dessus de la pile de tâches cible Android 15.
- Toutes les activités visibles sont activées pour les nouvelles protections
Si les mesures de sécurité sont activées, il est possible que les applis reviennent à l'écran d'accueil dernière application visible, s'il termine sa propre tâche.
Autres modifications
En plus de la restriction concernant la mise en correspondance des identifiants uniques, ces modifications inclus:
- Modifiez les créateurs
PendingIntent
pour qu'ils bloquent les activités en arrière-plan en par défaut. Cela permet d'éviter que les applications ne créent accidentellementPendingIntent
susceptibles d'être utilisés de manière abusive par des acteurs malveillants. - Ne mettez une application au premier plan que si l'expéditeur
PendingIntent
le permet. Ce changement vise à empêcher les applications malveillantes d'utiliser abusivement les Possibilité de démarrer des activités en arrière-plan Par défaut, les applications ne sont pas autorisé à faire passer la pile de tâches au premier plan, sauf si le créateur l'autorise droits de lancement de l'activité en arrière-plan ou si l'expéditeur a une activité en arrière-plan les droits de lancement. - Contrôlez la façon dont l'activité principale d'une pile de tâches peut terminer sa tâche. Si le l'activité principale termine une tâche, Android revient à la tâche dernière activité. De plus, si une activité non principale termine sa tâche, Android retournez à l'écran d'accueil, il ne bloquera pas l'arrivée activité.
- Empêcher le lancement d'activités arbitraires provenant d'autres applications dans la vôtre tâche. Ce changement empêche les applications malveillantes d'hameçonnage des utilisateurs en créant activités qui semblent provenir d'autres applications.
- Empêcher les fenêtres non visibles d'être prises en compte pour l'activité en arrière-plan lancements. Cela permet d'éviter que les applications malveillantes utilisent l'arrière-plan de manière abusive. se lance pour présenter du contenu indésirable ou malveillant aux utilisateurs.
Intents plus sécurisés
Android 15 introduit de nouvelles mesures de sécurité pour renforcer la sécurité des intents robustes. Ces changements visent à prévenir les vulnérabilités potentielles et usage abusif d'intents pouvant être exploités par des applications malveillantes. Il existe deux principaux Améliorations apportées à la sécurité des intents dans Android 15:
- Faire correspondre les filtres d'intent cibles:les intents qui ciblent des composants spécifiques doivent correspondent précisément aux spécifications de filtre d'intent de la cible. Si vous envoyez une pour lancer l'activité d'une autre application, le composant d'intent cible doit s'aligner sur les filtres d'intent déclarés de l'activité de réception.
- Les intents doivent comporter des actions:les intents sans action ne seront plus mis en correspondance. tous les filtres d'intent. Cela signifie que les intents utilisés pour démarrer des activités services doivent être clairement définis.
- Intents en attente:le créateur de l'intent en attente est traité comme l'expéditeur de l'intent englobant, et non comme l'expéditeur de l'intent en attente intention
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Expérience utilisateur et UI du système
Android 15 inclut certaines modifications visant à créer un environnement plus cohérent, une expérience utilisateur intuitive.
Modifications de l'encart de la fenêtre
Il existe deux modifications liées aux encarts de fenêtre dans Android 15: l'application bord à bord est appliquée par défaut, et il existe également des modifications de configuration, telles que la configuration par défaut des barres système.
Application bord à bord
Les applications sont bord à bord par défaut sur les appareils équipés d'Android 15 si elles sont ciblant Android 15 (niveau d'API 35).
<ph type="x-smartling-placeholder">Il s'agit d'une modification destructive qui pourrait avoir un impact négatif sur l'interface utilisateur de votre application. La les modifications affectent les zones d'interface utilisateur suivantes:
- Barre de navigation par gestes
<ph type="x-smartling-placeholder">
- </ph>
- Transparent par défaut.
- Le décalage inférieur est désactivé afin que le contenu s'affiche derrière la navigation système sauf si des encarts sont appliqués.
setNavigationBarColor
etR.attr#navigationBarColor
sont obsolète et n'affectent pas la navigation par gestes.setNavigationBarContrastEnforced
etR.attr#navigationBarContrastEnforced
n'ont toujours aucun effet sur la navigation par gestes.
- Navigation à trois boutons
<ph type="x-smartling-placeholder">
- </ph>
- L'opacité est définie sur 80% par défaut, et la couleur peut correspondre à celle de la fenêtre. en arrière-plan.
- Décalage inférieur désactivé afin que le contenu s'affiche derrière la barre de navigation système sauf si des encarts sont appliqués.
setNavigationBarColor
etR.attr#navigationBarColor
sont définie pour correspondre à l'arrière-plan de la fenêtre par défaut. Arrière-plan de la fenêtre doit être un drawable couleur pour que cette valeur par défaut s'applique. Cette API est obsolète mais continue à affecter la navigation à trois boutons.setNavigationBarContrastEnforced
etR.attr#navigationBarContrastEnforced
est défini sur "true" par défaut, ce qui ajoute Arrière-plan opaque à 80% pour une navigation à trois boutons.
- Barre d'état
<ph type="x-smartling-placeholder">
- </ph>
- Transparent par défaut.
- Le décalage supérieur est désactivé afin que le contenu s'affiche derrière la barre d'état, sauf et des encarts sont appliqués.
setStatusBarColor
etR.attr#statusBarColor
sont obsolètes et n'ont aucun effet sur Android 15.setStatusBarContrastEnforced
etR.attr#statusBarContrastEnforced
sont obsolètes, mais ont toujours une sur Android 15.
- Encoche
<ph type="x-smartling-placeholder">
- </ph>
layoutInDisplayCutoutMode
des fenêtres non flottantes doivent êtreLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
SHORT_EDGES
,NEVER
et LesDEFAULT
sont interprétés commeALWAYS
, de sorte que les utilisateurs ne voient pas causée par l'encoche et s'affiche de bord à bord.
L'exemple suivant présente une application avant et après le ciblage Android 15 (niveau d'API 35), et avant et après l'application des encarts.
<ph type="x-smartling-placeholder">Comment vérifier si votre application est déjà de bord à bord ?
Si votre application est déjà bord à bord et applique des encarts, n'ont quasiment aucun impact, sauf dans les cas suivants. Cependant, même si vous pensez vous n'êtes pas concerné, nous vous recommandons de tester votre application.
- Vous disposez d'une fenêtre non flottante, telle qu'une
Activity
qui utiliseSHORT_EDGES
,NEVER
ouDEFAULT
au lieu deLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
Si votre application plante au lancement, en raison de votre écran de démarrage. Vous pouvez soit mettre à niveau le core splashscreen par rapport à 1.2.0-alpha01 ou une version ultérieure, ou définissezwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Il est possible que l'interface utilisateur soit masquée sur des écrans à faible trafic. Vérifier ces éléments
les écrans moins consultés n'ont pas d'interface utilisateur obstruée. Les écrans qui affichent moins de trafic sont les suivants:
<ph type="x-smartling-placeholder">
- </ph>
- Écrans d'accueil ou de connexion
- Pages de paramètres
Vérifier si votre application n'est pas déjà bord à bord
Si votre application n'est pas déjà bord à bord, vous êtes probablement affecté. Dans en plus des scénarios d'applications déjà bord à bord, tenez compte des éléments suivants:
- Si votre application utilise des composants Material 3 (
androidx.compose.material3
) dans Compose, par exempleTopAppBar
,BottomAppBar
etNavigationBar
, il est probable que ces composants ne soient pas car ils gèrent automatiquement les encarts. - Si votre application utilise des composants Material 2 (
androidx.compose.material
) dans Compose, ces composants ne gèrent pas automatiquement les encarts. Cependant, vous pouvez accéder aux encarts et les appliquer manuellement. Dans androidx.compose.material 1.6.0 puis utilisez le paramètrewindowInsets
pour appliquer les encarts manuellementBottomAppBar
,TopAppBar
BottomNavigation
etNavigationRail
. De même, utilisez le paramètrecontentWindowInsets
pourScaffold
- Si votre application utilise des vues et des composants Material
(
com.google.android.material
), Material Design principalement basé sur les vues Des composants tels queBottomNavigationView
,BottomAppBar
,NavigationRailView
ouNavigationView
gèrent les encarts et ne nécessitent aucune travail supplémentaire. Cependant, vous devez ajouterandroid:fitsSystemWindows="true"
si vous utilisezAppBarLayout
. - Pour les composables personnalisés, appliquez manuellement les encarts en tant que marge intérieure. Si votre
contenu dans un
Scaffold
, vous pouvez utiliser des encarts à l'aide de l'Scaffold
les valeurs de marge intérieure. Sinon, appliquez une marge intérieure à l'aide de l'une desWindowInsets
- Si votre application utilise des vues et des
BottomSheet
,SideSheet
ou personnalisées des conteneurs, appliquez un remplissage à l'aide deViewCompat.setOnApplyWindowInsetsListener
PourRecyclerView
, appliquer une marge intérieure à l'aide de cet écouteur et ajouterclipToPadding="false"
Points à vérifier si votre application doit proposer une protection personnalisée en arrière-plan
Si votre application doit offrir une protection personnalisée en arrière-plan pour la navigation à trois boutons ou
la barre d'état, votre application doit placer un composable ou une vue derrière la barre système
avec WindowInsets.Type#tappableElement()
pour obtenir les trois boutons
hauteur de la barre de navigation ou WindowInsets.Type#statusBars
.
Ressources de bord à bord supplémentaires
Consultez les vues Edge à Edge et Edge to Edge Compose. pour en savoir plus sur l'application d'encarts.
API obsolètes
Les API suivantes sont désormais obsolètes:
R.attr#enforceStatusBarContrast
R.attr#navigationBarColor
R.attr#navigationBarDividerColor
R.attr#statusBarColor
Window#getNavigationBarColor
Window#getNavigationBarDividerColor
Window#getStatusBarColor
Window#isStatusBarContrastEnforced
Window#setDecorFitsSystemWindows
Window#setNavigationBarColor
Window#setNavigationBarDividerColor
Window#setStatusBarColor
Window#setStatusBarContrastEnforced
Configuration stable
Si votre application cible Android 15 (niveau d'API 35) ou une version ultérieure, Configuration
non
exclut plus longtemps
les barres système. Si vous utilisez la taille de l'écran dans la classe Configuration
pour le calcul de la mise en page, vous devez la remplacer par de meilleures alternatives, comme un ViewGroup
, WindowInsets
ou WindowMetricsCalculator
approprié, en fonction de vos besoins.
Configuration
est disponible depuis l'API 1. Elle est généralement obtenue à partir de
Activity.onConfigurationChanged
Il fournit des informations telles que
la densité des fenêtres,
l'orientation et les tailles. Une caractéristique importante des tailles de fenêtre renvoyées par Configuration
est qu'elles excluaient auparavant les barres système.
La taille de configuration sert généralement à sélectionner des ressources, par exemple
/res/layout-h500dp
, et ce cas d'utilisation reste valide. Cependant, son utilisation pour
le calcul de mise en page a toujours été déconseillé. Si c'est le cas, vous devez vous en éloigner immédiatement. Vous devez remplacer l'utilisation de Configuration
par quelque chose
plus adapté à votre cas d'utilisation.
Si vous l'utilisez pour calculer la mise en page, utilisez un ViewGroup
approprié, tel que CoordinatorLayout
ou ConstraintLayout
. Si vous l'utilisez pour déterminer la hauteur de la barre de navigation du système, utilisez WindowInsets
. Si vous voulez connaître la taille actuelle
de la fenêtre de votre application, utilisez computeCurrentWindowMetrics
.
La liste suivante décrit les champs concernés par cette modification :
- Les tailles
Configuration.screenWidthDp
etscreenHeightDp
ne sont plus disponibles exclure les barres système. Configuration.smallestScreenWidthDp
est indirectement affecté par les modifications apportées àscreenWidthDp
etscreenHeightDp
.Configuration.orientation
est indirectement affecté par les modifications apportées àscreenWidthDp
etscreenHeightDp
sur les appareils presque carrés.Display.getSize(Point)
est indirectement affecté par les modifications apportées àConfiguration
Cette méthode a été abandonnée à partir du niveau d'API 30.Display.getMetrics()
fonctionne déjà de cette manière depuis le niveau d'API 33.
Par défaut, l'attribut élégantTextHeight est défini sur "true".
Pour les applications ciblant Android 15, l'attribut elegantTextHeight
TextView
devient true
par défaut, en remplaçant la police compacte utilisée par défaut par certains scripts associés à de grandes métriques verticales par un autre plus lisible. La police compacte a été introduite pour éviter de perturber les mises en page. Android 13 (niveau d'API 33) empêche bon nombre de ces failles en permettant à la mise en page du texte d'étirer la hauteur verticale à l'aide de l'attribut fallbackLineSpacing
.
Dans Android 15, la police compacte reste dans le système. Votre application peut donc définir elegantTextHeight
sur false
pour obtenir le même comportement qu'auparavant, mais elle ne sera probablement pas compatible avec les prochaines versions. Ainsi, si votre application est compatible avec les scripts suivants (arabe, laotien, birman, gujarati, kannada, malayalam, odia, télougou ou thaï), testez-la en définissant elegantTextHeight
sur true
.
Modifications de la largeur de TextView pour les lettres complexes
Dans les versions précédentes d'Android, certaines polices cursives ou certaines langues
une forme complexe pourrait dessiner les lettres dans la zone du caractère précédent ou suivant.
Dans certains cas, ces lettres étaient tronquées au début ou à la fin.
À partir d'Android 15, TextView
alloue une largeur pour dessiner suffisamment d'espace.
pour ces lettres et permet aux applications de demander des marges intérieures supplémentaires à gauche pour
empêcher le rognage.
Comme ce changement affecte la façon dont un TextView
décide de la largeur, TextView
alloue plus de largeur par défaut si l'application cible Android 15 (niveau d'API 35) ;
plus élevée. Vous pouvez activer ou désactiver ce comportement en appelant la méthode
API setUseBoundsForWidth
sur TextView
.
L'ajout d'une marge intérieure à gauche peut entraîner un désalignement pour les mises en page existantes. Par conséquent,
aucune marge intérieure n'est ajoutée par défaut, même pour les applications qui ciblent Android 15 ou version ultérieure.
Toutefois, vous pouvez ajouter une marge intérieure supplémentaire pour empêcher le rognage en appelant
setShiftDrawingOffsetForStartOverhang
Les exemples suivants montrent comment ces modifications peuvent améliorer la mise en page du texte pour certains les polices et les langues.
Hauteur de ligne par défaut en fonction des paramètres régionaux pour EditText
Dans les versions précédentes d'Android, la mise en page du texte étirait la hauteur du texte afin qu'elle corresponde à la hauteur de la ligne de la police correspondant aux paramètres régionaux actuels. Par exemple, si le contenu était en japonais, car la hauteur de ligne de la police japonaise est légèrement supérieure à celle d'une police latine, la hauteur du texte est devenue légèrement plus importante. Toutefois, malgré ces différences de hauteur de ligne, l'élément EditText
a été dimensionné de manière uniforme, quels que soient les paramètres régionaux utilisés, comme illustré dans l'image suivante:
Pour les applications ciblant Android 15, une hauteur de ligne minimale est désormais réservée à EditText
afin qu'il corresponde à la police de référence pour les paramètres régionaux spécifiés, comme illustré dans l'image suivante:
Si nécessaire, votre application peut restaurer le comportement précédent en spécifiant l'attribut useLocalePreferredLineHeightForMinimum
sur false
. Elle peut également définir des métriques verticales minimales personnalisées à l'aide de l'API setMinimumFontMetrics
en Kotlin et Java.
Appareil photo et contenus multimédias
Android 15 apporte les modifications suivantes au comportement de l'appareil photo et des contenus multimédias pour les applications qui ciblent Android 15 ou version ultérieure.
Restrictions concernant la demande de priorité audio
Les applications qui ciblent Android 15 doivent être l'application principale ou exécuter un service de premier plan pour demander la priorité audio. Si une application tente de demander la sélection alors qu'elle ne répond pas à l'une de ces exigences, l'appel renvoie AUDIOFOCUS_REQUEST_FAILED
.
Pour en savoir plus sur la priorité audio, consultez Gérer la priorité audio.
Mise à jour des restrictions non SDK
Android 15 inclut des listes à jour de listes d'autorisations non SDK limitées grâce à une collaboration avec des développeurs Android tests internes. Dans la mesure du possible, nous nous assurons que des alternatives publiques sont disponibles avant de limiter les interfaces non SDK.
Si votre application ne cible pas Android 15, certaines de ces modifications ne vous affecteront peut-être pas immédiatement. Cependant, bien que votre application puisse accéder à 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 vous ne savez pas si votre application utilise des interfaces non SDK, vous pouvez Testez votre application pour le savoir. Si votre application repose sur un outil non SDK vous devez commencer à planifier une migration vers des alternatives SDK. Néanmoins, nous comprenons que certaines applications ont des cas d'utilisation valables interfaces non SDK. Si vous ne trouvez pas d'alternative à l'utilisation d'un autre SDK d'une fonctionnalité de votre application, vous devez demander une nouvelle API publique.
Pour en savoir plus sur les modifications apportées à cette version d'Android, consultez Mises à jour des restrictions des interfaces non SDK dans Android 15. Pour en savoir plus sur les interfaces non SDK de manière générale, consultez la section Restrictions concernant les interfaces non SDK.