Comme dans les versions précédentes, Android 15 apporte des modifications de comportement susceptibles d'affecter votre application. Les modifications de comportement suivantes s'appliquent exclusivement aux applications qui ciblent Android 15 ou version ultérieure. Si votre application cible Android 15 ou une version ultérieure, vous devez la modifier pour qu'elle prenne en charge ces comportements, le cas échéant.
Veillez également à consulter la liste des modifications de comportement qui affectent toutes les applications exécutées sur Android 15, quel que soit le 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.
- Nouveau type de service de premier plan pour le traitement multimédia
- Restrictions concernant les broadcast receivers
BOOT_COMPLETED
qui lancent les services de premier plan
Comportement du délai avant expiration du service de premier plan pour la synchronisation des données
Android 15 introduces a new timeout behavior to dataSync
for apps targeting
Android 15 or higher. This behavior also applies to the new mediaProcessing
foreground service type.
The system permits an app's dataSync
services to run for a total of 6 hours
in a 24-hour period, after which the system calls the running service's
Service.onTimeout(int, int)
method (introduced in Android
15). At this time, the service has a few seconds to call
Service.stopSelf()
. When Service.onTimeout()
is called, the
service is no longer considered a foreground service. If the service does not
call Service.stopSelf()
, a failure will occur with this error message: "A
foreground service of
<fgs_type> did not stop within its timeout:
<component_name>". In Beta 2, the failure message is shown as an
ANR, but in a future Beta release, this failure message will throw a custom
exception.
To avoid problems with this behavior change, you can do one or more of the following:
- Have your service implement the new
Service.onTimeout(int, int)
method. When your app receives the callback, make sure to callstopSelf()
within a few seconds. (If you don't stop the app right away, the system generates a failure.) - Make sure your app's
dataSync
services don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer). - Only start
dataSync
foreground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background. - Instead of using a
dataSync
foreground service, use an alternative API.
If your app's dataSync
foreground services have run for 6 hours in the last
24, you cannot start another dataSync
foreground service unless the user
has brought your app to the foreground (which resets the timer). If you try to
start another dataSync
foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type dataSync".
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 type de service est adapté à des opérations telles que le transcodage de fichiers multimédias. Par exemple, une application multimédia peut télécharger un fichier audio et doit le convertir dans un autre format avant de le lire. Vous pouvez utiliser un service de premier plan mediaProcessing
pour vous assurer que la conversion se poursuit même lorsque l'application est exécutée en arrière-plan.
Le système permet aux services mediaProcessing
d'une application de s'exécuter pendant six heures au total sur une période de 24 heures, après quoi le système appelle la méthode Service.onTimeout(int, int)
du service en cours d'exécution (introduit dans Android 15). À ce stade, le service dispose de quelques secondes pour appeler Service.stopSelf()
. Si le service n'appelle pas Service.stopSelf()
, un échec se produira avec le message d'erreur suivant: "Un service de premier plan de <fgs_type> ne s'est pas arrêté pendant son délai d'inactivité : <component_name>". Dans la version bêta 2, le message d'échec s'affiche en tant qu'erreur ANR, mais dans une prochaine version bêta, ce message d'échec générera une exception personnalisée.
Pour éviter d'obtenir une erreur ANR, 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()
en quelques secondes. (Si vous n'arrêtez pas l'application immédiatement, le système génère une défaillance.) - Assurez-vous que les services
mediaProcessing
de votre application ne s'exécutent pas pendant plus de six heures sur une période de 24 heures (sauf si l'utilisateur interagit avec l'application, en réinitialisant le minuteur). - Ne démarrez les services de premier plan
mediaProcessing
qu'à la suite d'une interaction directe de l'utilisateur. Étant donné que votre application est au premier plan au démarrage du service, votre service dispose des six heures complètes après que l'application passe en arrière-plan. - Au lieu d'utiliser un service de premier plan
mediaProcessing
, utilisez une API alternative, telle que WorkManager.
Si les services de premier plan mediaProcessing
de votre application ont été exécutés pendant six heures au cours des 24 dernières, vous ne pouvez pas démarrer un autre service de premier plan mediaProcessing
sauf si l'utilisateur a placé 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 une erreur ForegroundServiceStartNotAllowedException
avec un message d'erreur du type "Time limit already exceeded for premier plan service type mediaProcessing".
Pour en savoir plus sur le type de service mediaProcessing
, consultez Modifications apportées aux types de services de premier plan pour Android 15: traitement multimédia.
Restrictions concernant les broadcast receivers BOOT_COMPLETED
qui lancent les services de premier plan
There are new restrictions on BOOT_COMPLETED
broadcast receivers launching
foreground services. BOOT_COMPLETED
receivers are not allowed to launch the
following types of foreground services:
dataSync
camera
mediaPlayback
phoneCall
mediaProjection
microphone
(this restriction has been in place formicrophone
since Android 14)
If a BOOT_COMPLETED
receiver tries to launch any of those types of foreground
services, the system throws ForegroundServiceStartNotAllowedException
.
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 lancer un service de premier plan même si l'application était actuellement en arrière-plan (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 disposer d'une fenêtre en superposition visible. Autrement dit, l'application doit d'abord lancer une fenêtre TYPE_APPLICATION_OVERLAY
et celle-ci doit être visible avant de démarrer un service de premier plan.
Si votre application tente de démarrer un service de premier plan à partir de l'arrière-plan sans remplir ces nouvelles exigences (et qu'elle ne dispose pas d'une autre exception), le système génère une exception ForegroundServiceStartNotAllowedException
.
Si votre application déclare l'autorisation SYSTEM_ALERT_WINDOW
et lance des services de premier plan en arrière-plan, elle peut être affectée par cette modification. Si votre application reçoit un ForegroundServiceStartNotAllowedException
, vérifiez l'ordre des opérations et assurez-vous qu'elle dispose déjà d'une fenêtre de superposition active avant de tenter de démarrer un service de premier plan en arrière-plan. Vous pouvez vérifier si votre fenêtre de superposition est actuellement visible en appelant View.getWindowVisibility()
. Vous pouvez également ignorer View.onWindowVisibilityChanged()
afin d'être averti chaque fois que la visibilité change.
Modification des conditions dans lesquelles les applications peuvent modifier l'état général du mode Ne pas déranger
Apps that target Android 15 can no longer change the global state or policy of
Do Not Disturb (DND) on a device (either by modifying user settings, or turning
off DND mode). Instead, apps must contribute an AutomaticZenRule
, which
the system combines into a global policy with the existing
most-restrictive-policy-wins scheme. Calls to existing APIs that previously
affected global state (setInterruptionFilter
,
setNotificationPolicy
) result in the creation or update of an
implicit AutomaticZenRule
, which is toggled on and off depending on the
call-cycle of those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL)
and expects that call to
deactivate an AutomaticZenRule
that was previously activated by their owners.
Modifications d'OpenJDK 17
Android 15 poursuit le travail d'actualisation des bibliothèques principales d'Android pour s'aligner sur les fonctionnalités des dernières versions d'OpenJDK LTS.
L'un des changements suivants peut affecter la compatibilité des applications ciblant Android 15:
Modifications apportées aux API de mise en forme de chaînes: la validation de l'index d'argument, des indicateurs, de la largeur et de la précision est désormais plus stricte lors de l'utilisation des API
String.format()
etFormatter.format()
suivantes:String.format(String, Object[])
String.format(Locale, String, Object[])
Formatter.format(String, Object[])
Formatter.format(Locale, String, Object[])
Par exemple, l'exception suivante est générée lorsqu'un index d'argument de 0 est utilisé (
%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 indice d'argument de 1 (
%1
dans la chaîne de format).Modifications du type de composant de
Arrays.asList(...).toArray()
: lorsque vous utilisezArrays.asList(...).toArray()
, le type de composant du tableau obtenu est désormaisObject
, et non le type des éléments du tableau sous-jacent. Par conséquent, 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 tableau obtenu, vous pouvez utiliserCollection.toArray(Object[])
à la place:String[] elements = Arrays.asList("two", "one").toArray(new String[0]);
Modification du traitement du code de langue: lorsque vous utilisez l'API
Locale
, les codes des langues pour l'hébreu, le yiddish et l'indonésien ne sont plus convertis dans leurs formes obsolètes (hébreu:iw
, yiddish:ji
et indonésien:in
). Lorsque vous spécifiez le code de langue pour l'une de ces langues, utilisez plutôt les codes ISO 639-1 (hébreu:he
, indonésien:yi
0 et yiddish) :id
Modifications apportées aux séquences d'entrée aléatoires: suite aux modifications apportées dans https://bugs.openjdk.org/Browse/JDK-8301574, les méthodes
Random.ints()
suivantes renvoient désormais une séquence de nombres différente de celle des méthodesRandom.nextInt()
:En règle générale, cette modification ne devrait pas entraîner de dysfonctionnement de l'application, mais votre code ne doit pas s'attendre à ce que la séquence générée à partir des méthodes
Random.ints()
corresponde àRandom.nextInt()
.
Sécurité
Android 15 inclut des modifications qui renforcent la sécurité du système afin de protéger les applications et les utilisateurs contre les applications malveillantes.
Lancement sécurisé des activités en arrière-plan
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 d'arrière-plan de mettre d'autres applications au premier plan, d'élever leurs privilèges et d'abuser des interactions utilisateur. Le lancement de l'activité en arrière-plan est limité depuis Android 10 (niveau d'API 29).
Empêcher les applications qui ne correspondent pas à l'UID principal de la pile de lancer des activités
Des applications malveillantes peuvent lancer l'activité d'une autre application dans la même tâche, puis se superposer, ce qui donne l'illusion d'être cette application. Cette attaque de "détournement de tâches" contourne les restrictions actuelles de lancement en arrière-plan, car elle se déroule toutes dans la même tâche visible. Pour atténuer ce risque, Android 15 ajoute un indicateur qui empêche les applications qui ne correspondent pas à l'UID principal de la pile de lancer des activités. Pour activer toutes les activités de votre application, mettez à jour l'attribut 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 qui effectue le lancement cible Android 15.
- L'application située au-dessus de la pile de tâches cible Android 15.
- Les nouvelles protections sont activées pour toute activité visible.
Si les mesures de sécurité sont activées, les applications peuvent revenir à l'accueil plutôt que la dernière application visible si elles terminent leur propre tâche.
Autres modifications
En plus de la restriction de la correspondance UID, les modifications suivantes sont également incluses:
- Modifiez les créateurs
PendingIntent
pour qu'ils bloquent le lancement des activités en arrière-plan par défaut. Cela empêche les applications de créer accidentellement unPendingIntent
susceptible d'être utilisé de manière abusive par des acteurs malveillants. - N'affichez une application au premier plan que si l'expéditeur
PendingIntent
le permet. Ce changement vise à empêcher les applications malveillantes d'abuser de la possibilité de démarrer des activités en arrière-plan. Par défaut, les applications ne sont pas autorisées à placer la pile de tâches au premier plan, sauf si le créateur autorise les droits de lancement des activités en arrière-plan ou si l'expéditeur dispose de droits de lancement des activités en arrière-plan. - Contrôlez la manière dont l'activité principale d'une pile de tâches peut terminer sa tâche. Si l'activité principale termine une tâche, Android revient à la dernière tâche active. De plus, si une activité non principale termine sa tâche, Android revient à l'écran d'accueil. Il ne bloque pas la fin de cette activité.
- Empêchez le lancement d'activités arbitraires provenant d'autres applications dans votre propre tâche. Ce changement empêche les applications malveillantes d'attaquer les utilisateurs d'hameçonnage en créant des activités qui semblent provenir d'autres applications.
- Empêchez les fenêtres non visibles d'être prises en compte pour le lancement d'activités d'arrière-plan. Cela permet d'empêcher les applications malveillantes d'utiliser de manière abusive les lancements d'activités en arrière-plan pour afficher du contenu indésirable ou malveillant auprès des utilisateurs.
Intents plus sûrs
Android 15 introduit de nouvelles mesures de sécurité pour renforcer la sécurité et la robustesse des intents. Ces modifications visent à prévenir les failles potentielles et l'utilisation abusive d'intents susceptibles d'être exploités par des applications malveillantes. Il existe deux améliorations principales pour la sécurité des intents dans Android 15:
- Faire correspondre les filtres d'intent cibles:les intents qui ciblent des composants spécifiques doivent correspondre précisément aux spécifications de filtre d'intent de la cible. Si vous envoyez un intent pour lancer l'activité d'une autre application, le composant d'intent cible doit s'aligner avec les filtres d'intent déclarés de l'activité de réception.
- Les intents doivent comporter des actions:les intents sans action ne correspondront à aucun filtre d'intent. Cela signifie que les intents utilisés pour démarrer des activités ou des services doivent avoir une action clairement définie.
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 des modifications destinées à créer une expérience utilisateur plus cohérente et intuitive.
Modifications des encarts de 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 ciblent Android 15.
Il s'agit d'une modification destructive qui pourrait avoir un impact négatif sur l'UI de votre application. Les modifications affectent les domaines de l'interface utilisateur suivants:
- Barre de navigation par poignée de gestes
- Transparence par défaut.
- Le décalage inférieur est désactivé, de sorte que le contenu s'affiche derrière la barre de navigation du système, sauf si des encarts sont appliqués.
setNavigationBarColor
etR.attr#navigationBarColor
sont obsolètes et n'affectent pas la navigation par gestes.setNavigationBarContrastEnforced
etR.attr#navigationBarContrastEnforced
restent sans effet sur la navigation par gestes.
- Navigation à trois boutons
- Opacité définie sur 80% par défaut, la couleur correspondant peut-être à l'arrière-plan de la fenêtre.
- Le décalage inférieur est désactivé, de sorte que le contenu s'affiche derrière la barre de navigation du système, sauf si des encarts sont appliqués.
setNavigationBarColor
etR.attr#navigationBarColor
sont définis par défaut pour correspondre à l'arrière-plan de la fenêtre. L'arrière-plan de la fenêtre doit être un drawable de couleur pour que cette valeur par défaut s'applique. Cette API est obsolète, mais continue d'affecter la navigation à trois boutons.setNavigationBarContrastEnforced
etR.attr#navigationBarContrastEnforced
sont définis sur "true" par défaut, ce qui ajoute un arrière-plan opaque de 80% pour la navigation à trois boutons.
- Barre d'état
- Transparence par défaut.
- Le décalage supérieur est désactivé, de sorte que le contenu s'affiche derrière la barre d'état, sauf si 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 un impact sur Android 15.
- Encoche
layoutInDisplayCutoutMode
des fenêtres non flottantes doit êtreLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
.SHORT_EDGES
,NEVER
etDEFAULT
sont interprétés commeALWAYS
afin que les utilisateurs ne voient pas de barre noire causée par l'encoche et s'affichent bord à bord.
L'exemple suivant montre une application avant et après le ciblage d'Android 15, et avant et après l'application d'encarts.
Ce que vous devez vérifier si votre application est déjà bord à bord
Si votre application est déjà bord à bord et applique des encarts, elle n'est pratiquement pas affectée, sauf dans les scénarios suivants. Toutefois, même si vous pensez ne pas être affecté, 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, cela peut être dû à votre écran de démarrage. Vous pouvez mettre à niveau la dépendance de l'écran de démarrage principal vers 1.2.0-alpha01 ou une version ultérieure, ou définirwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always
. - Certains écrans à faible trafic peuvent être masqués. Vérifiez que l'interface utilisateur n'est pas masquée sur ces écrans les moins consultés. Les écrans à faible trafic incluent :
- Écrans d'intégration ou de connexion
- Pages de paramètres
Ce qu'il faut vérifier si votre application n'est pas déjà bord à bord
Si votre application n'est pas déjà bord à bord, vous êtes très probablement concerné. En plus des scénarios pour les applications déjà bord à bord, vous devez tenir compte des points suivants:
- Si votre application utilise des composants Material 3 (
androidx.compose.material3
) dans Compose, tels queTopAppBar
,BottomAppBar
etNavigationBar
, ces composants ne sont probablement pas concernés, 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. Toutefois, vous pouvez accéder aux encarts et les appliquer manuellement. Dans androidx.compose.material 1.6.0 et les versions ultérieures, utilisez le paramètrewindowInsets
pour appliquer manuellement les encarts pourBottomAppBar
,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
), la plupart des composants Material basés sur des vues tels queBottomNavigationView
,BottomAppBar
,NavigationRailView
ouNavigationView
gèrent les encarts et ne nécessitent aucune tâche supplémentaire. Toutefois, vous devez ajouterandroid:fitsSystemWindows="true"
si vous utilisezAppBarLayout
. - Pour les composables personnalisés, appliquez les encarts manuellement en tant que marge intérieure. Si votre contenu se trouve dans une
Scaffold
, vous pouvez utiliser les encarts à l'aide des valeurs de marge intérieureScaffold
. Sinon, appliquez une marge intérieure à l'aide de l'une des optionsWindowInsets
. - Si votre application utilise des vues et
BottomSheet
,SideSheet
ou des conteneurs personnalisés, appliquez une marge intérieure à l'aide deViewCompat.setOnApplyWindowInsetsListener
. PourRecyclerView
, appliquez une marge intérieure à l'aide de cet écouteur et ajoutez égalementclipToPadding="false"
.
Que vérifier si votre application doit offrir une protection personnalisée en arrière-plan ?
Si votre application doit offrir une protection d'arrière-plan personnalisée à la navigation à trois boutons ou à la barre d'état, elle doit placer un composable ou une vue derrière la barre système à l'aide de WindowInsets.Type#tappableElement()
pour obtenir la hauteur de la barre de navigation à trois boutons ou WindowInsets.Type#statusBars
.
Ressources de périphérie supplémentaires
Consultez les guides Vues Edge to Edge et Edge to Edge Compose Pour obtenir des informations supplémentaires 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 ou une version ultérieure, Configuration
n'exclut plus les barres système. Si vous utilisez la taille d'écran dans la classe Configuration
pour calculer la mise en page, vous devez la remplacer par de meilleures alternatives, telles que ViewGroup
, WindowInsets
ou WindowMetricsCalculator
, selon vos besoins.
Configuration
est disponible depuis l'API 1. Elle est généralement obtenue à partir de Activity.onConfigurationChanged
. Elle fournit des informations telles que la densité, l'orientation et les tailles de la fenêtre. Une caractéristique importante des tailles de fenêtre renvoyées par Configuration
est qu'elle excluait auparavant les barres système.
La taille de la configuration est généralement utilisée pour sélectionner des ressources, par exemple /res/layout-h500dp
, et cela reste un cas d'utilisation valide. Cependant, son utilisation pour calculer la mise en page a toujours été déconseillée. Si vous le faites, vous devez
vous en éloigner maintenant. Vous devez remplacer l'utilisation de Configuration
par quelque chose de 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 souhaitez 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
n'excluent plus 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 proches du carré.Display.getSize(Point)
est indirectement affecté par les modifications apportées àConfiguration
. Cette fonctionnalité a été abandonnée à partir du niveau d'API 30.Display.getMetrics()
fonctionne déjà comme ceci depuis le niveau d'API 33.
L'attribut élégantTextHeight est défini par défaut 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
.
Modification de la largeur de TextView pour les formes de lettres complexes
Dans les versions précédentes d'Android, certaines polices cursives ou certaines langues présentant une mise en forme complexe peuvent 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, un 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 éviter le rognage.
Étant donné que cette modification affecte la façon dont un TextView
détermine la largeur, TextView
alloue plus de largeur par défaut si l'application cible Android 15 ou version ultérieure. Vous pouvez activer ou désactiver ce comportement en appelant l'API setUseBoundsForWidth
sur TextView
.
L'ajout d'une marge intérieure à gauche peut entraîner un désalignement pour les mises en page existantes. C'est pourquoi cette marge intérieure n'est pas 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 certaines polices et langues.
Hauteur de ligne par défaut 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 contenu multimédia
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 les demandes de priorité audio
Apps that target Android 15 must be the top app or running an
audio-related foreground service in order to request audio focus. If an app
attempts to request focus when it does not meet one of these requirements, the
call returns AUDIOFOCUS_REQUEST_FAILED
.
A foreground service is considered audio-related if its type is
mediaPlayback
, camera
, microphone
, or phoneCall
.
You can learn more about audio focus at Manage audio focus.
Mise à jour des restrictions non SDK
Android 15 inclut des listes à jour d'interfaces non SDK limitées grâce à la collaboration avec les développeurs Android et aux derniers 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. Toutefois, bien qu'il soit possible pour votre application d'accéder à certaines interfaces non SDK en fonction du niveau d'API cible de votre application, l'utilisation d'une méthode ou d'un champ 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 tester votre application pour le savoir. Si votre application repose sur des interfaces non SDK, vous devez commencer à planifier une migration vers des alternatives SDK. Néanmoins, nous comprenons que certaines applications ont des cas d'utilisation valides concernant l'utilisation d'interfaces non SDK. Si vous ne trouvez pas d'alternative à l'utilisation d'une interface non SDK pour 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.