Le mode multifenêtre permet à plusieurs applications de partager le même écran simultanément. Les applications peuvent être côte à côte ou l'une au-dessus de l'autre (mode Écran partagé), l'une dans une petite fenêtre superposée aux autres (mode Picture-in-picture), ou chacune dans une fenêtre mobile séparée et redimensionnable (mode Fenêtres de bureau).
Pour obtenir des instructions sur l'accès au mode Écran partagé sur les téléphones, consultez Afficher deux applications simultanément sur un téléphone Pixel.
Fonctionnalités multifenêtre spécifiques à la version
L'expérience utilisateur multifenêtre dépend de la version d'Android et du type d'appareil:
Android 7.0 (niveau d'API 24) introduit le mode Écran partagé sur les petits écrans et le mode Picture-in-picture sur certains appareils.
Le mode Écran partagé remplit l'écran avec deux applications qui s'affichent côte à côte ou l'une au-dessus de l'autre. Les utilisateurs peuvent faire glisser le séparateur situé entre les deux applications pour agrandir l'une ou l'autre.
Le mode Picture-in-picture permet aux utilisateurs de continuer la lecture de la vidéo tout en interagissant avec une autre application (voir la page concernant la fonctionnalité Picture-in-picture).
Les fabricants d'appareils à grand écran peuvent activer le mode fenêtrage du bureau, dans lequel les utilisateurs peuvent redimensionner librement chaque activité.
Vous pouvez configurer la manière dont votre application gère le mode multifenêtre en spécifiant les dimensions minimales autorisées de votre activité. Vous pouvez également désactiver le mode multifenêtre pour votre application en définissant
resizeableActivity="false"
afin que le système affiche toujours votre application en plein écran.
Android 8.0 (niveau d'API 26) étend le mode Picture-in-picture aux appareils à petit écran.
Android 12 (niveau d'API 31) rend le mode multifenêtre standard.
Sur les grands écrans (classe de taille de fenêtre moyenne ou agrandie), la plate-forme accepte toutes les applications en mode multifenêtre, quelle que soit la configuration. Si la valeur est
resizeableActivity="false"
, l'application passe en mode de compatibilité si nécessaire pour accueillir les dimensions d'affichage.Sur les petits écrans (classe de taille de fenêtre compacte), le système vérifie les valeurs
minWidth
etminHeight
d'une activité pour déterminer si elle peut s'exécuter en mode multifenêtre. SiresizeableActivity="false"
, l'application n'est pas autorisée à s'exécuter en mode multifenêtre, quelles que soient la largeur et la hauteur minimales.
Mode Écran partagé
Pour activer le mode Écran partagé, procédez comme suit:
- Ouvrez l'écran "Récents".
- Faites glisser une application pour l'afficher.
- Appuyez sur l'icône de l'application dans la barre de titre.
- Sélectionnez l'option "Écran partagé" dans le menu.
- Sélectionnez une autre application depuis l'écran "Récents", ou fermez l'écran "Récents" et exécutez une autre application.
Les utilisateurs quittent le mode Écran partagé en faisant glisser le séparateur de fenêtre vers le bord de l'écran (vers le haut ou vers le bas, vers la gauche ou vers la droite).
Lancer dans une fenêtre adjacente
Si votre application doit accéder au contenu par le biais d'un intent, vous pouvez utiliser FLAG_ACTIVITY_LAUNCH_ADJACENT
pour l'ouvrir dans une fenêtre d'écran partagé adjacente.
FLAG_ACTIVITY_LAUNCH_ADJACENT
a été introduit dans Android 7.0 (niveau d'API 24) pour permettre aux applications exécutées en mode Écran partagé de lancer des activités dans la fenêtre adjacente.
Android 12L (niveau d'API 32) et versions ultérieures ont étendu la définition de cet indicateur pour permettre aux applications exécutées en plein écran d'activer le mode Écran partagé, puis de lancer des activités dans la fenêtre adjacente.
Pour lancer une activité adjacente, utilisez conjointement FLAG_ACTIVITY_LAUNCH_ADJACENT
et FLAG_ACTIVITY_NEW_TASK
. Par exemple:
Kotlin
fun openUrlInAdjacentWindow(url: String) { Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or Intent.FLAG_ACTIVITY_NEW_TASK) }.also { intent -> startActivity(intent) } }
Java
public void openUrlInAdjacentWindow(String url) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); }
Cycle de vie d'une activité en mode multifenêtre
Le mode multifenêtre ne modifie pas le cycle de vie de l'activité. Cependant, l'état de reprise des applications dans plusieurs fenêtres varie selon les versions d'Android.
Multireprise
Android 10 (niveau d'API 29) et les versions ultérieures sont compatibles avec la fonctionnalité de multireprise. Toutes les activités restent à l'état RESUMED
lorsque l'appareil est en mode multifenêtre. Une activité peut être mise en pause si une activité transparente se superpose ou si elle ne peut pas être sélectionnée (par exemple, en mode Picture-in-picture). Il est également possible qu'aucune activité ne soit active à un moment donné, par exemple si le panneau des notifications est ouvert. La méthode onStop()
fonctionne comme d'habitude: elle est appelée chaque fois qu'une activité est supprimée de l'écran.
Le multireprise est également disponible sur certains appareils équipés d'Android 9 (niveau d'API 28). Pour activer la multireprise sur les appareils Android 9, ajoutez les métadonnées de fichier manifeste suivantes :
<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />
Pour vérifier qu'un appareil donné est compatible avec ces métadonnées du fichier manifeste, reportez-vous aux spécifications de l'appareil.
Android 9
En mode multifenêtre sur Android 9 (niveau d'API 28) ou une version antérieure, seule l'activité avec laquelle l'utilisateur a interagi le plus récemment est active à un moment donné. Cette activité est considérée comme la plus élevée et constitue la seule activité à l'état RESUMED
. Toutes les autres activités visibles sont STARTED
, mais pas RESUMED
.
Cependant, le système accorde une priorité plus élevée à ces activités visibles, mais non réactivées, qu'aux activités non visibles. Si l'utilisateur interagit avec l'une des activités visibles, celle-ci est réactivée et l'activité précédemment la plus élevée passe à l'état STARTED
.
Lorsqu'il y a plusieurs activités au sein d'un même processus applicatif actif, l'activité dont l'ordre de priorité est le plus élevé est reprise et les autres sont mises en veille.
Modifications de configuration
Lorsque l'utilisateur active une application en mode multifenêtre, le système notifie l'activité d'une modification de configuration comme spécifié dans Gérer les modifications de configuration. Cela se produit également lorsque l'utilisateur redimensionne l'application ou la remet en mode plein écran.
Ce changement a la même incidence sur le cycle de vie de l'activité que lorsque le système avertit l'application que l'appareil est passé de l'orientation portrait à l'orientation paysage. Seule différence : les dimensions de l'application sont modifiées au lieu d'être simplement permutées. Votre activité peut gérer elle-même le changement de configuration ou permettre au système de détruire l'activité et de la recréer avec les nouvelles dimensions.
Si l'utilisateur redimensionne une fenêtre et l'agrandit dans l'une ou l'autre dimension, le système redimensionne l'activité pour qu'elle corresponde à l'action utilisateur et modifie la configuration si nécessaire. Si l'application prend du retard dans le dessin de zones nouvellement exposées, le système les remplit temporairement avec la couleur spécifiée par l'attribut windowBackground
ou par l'attribut de style par défaut windowBackgroundFallback
.
Accès exclusif aux ressources
Pour faciliter la compatibilité de la fonctionnalité de multireprise, utilisez le rappel de cycle de vie onTopResumedActivityChanged()
.
Le rappel est appelé lorsqu'une activité gagne ou perd la première position réactivée, ce qui est important lorsqu'une activité utilise une ressource Singleton partagée, comme le micro ou l'appareil photo:
Kotlin
override fun onTopResumedActivityChanged(topResumed: Boolean) { if (topResumed) { // Top resumed activity. // Can be a signal to re-acquire exclusive resources. } else { // No longer the top resumed activity. } }
Java
@Override public void onTopResumedActivityChanged(boolean topResumed) { if (topResumed) { // Top resumed activity. // Can be a signal to re-acquire exclusive resources. } else { // No longer the top resumed activity. } }
Notez qu'une application peut perdre des ressources pour d'autres raisons, par exemple la suppression d'un équipement matériel.
Dans tous les cas, une application doit gérer de manière optimale les événements et les changements d'état qui affectent les ressources disponibles.
Pour les applications qui utilisent une caméra, CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged()
indique qu'il peut être judicieux d'essayer d'accéder à la caméra.
Cette méthode est disponible à partir d'Android 10 (niveau d'API 29).
N'oubliez pas que resizeableActivity=false
ne garantit pas un accès exclusif à la caméra, car les autres applications qui utilisent cette même fonctionnalité peuvent être ouvertes sur d'autres écrans.
Votre application n'a pas besoin de libérer la caméra lorsque celle-ci n'est plus au premier plan. Par exemple, vous pouvez continuer d'afficher l'aperçu de la caméra pendant que l'utilisateur interagit avec l'application qui vient d'être utilisée pour la première fois. Votre application peut continuer à exécuter la caméra lorsqu'il ne s'agit pas de l'application la plus réactivée, mais elle doit gérer le processus de déconnexion correctement. Lorsque l'application la plus réactivée souhaite utiliser l'appareil photo, elle pourra l'ouvrir et votre application perdra l'accès. Votre application peut rouvrir l'appareil photo lorsqu'elle récupère le premier plan.
Lorsqu'une application reçoit un rappel CameraDevice.StateCallback#onDisconnected()
, les appels suivants sur l'appareil photo génèrent une exception CameraAccessException
.
Multi-écran
Android 10 (niveau d'API 29) accepte les activités sur les écrans secondaires. Si une activité est exécutée sur un appareil avec plusieurs écrans, les utilisateurs peuvent la déplacer d'un écran à un autre. La fonctionnalité de multireprise s'applique également aux scénarios multi-écrans. Plusieurs activités peuvent recevoir en même temps des entrées utilisateur.
Une application peut spécifier l'écran sur lequel elle doit s'exécuter lorsqu'elle se lance ou lorsqu'elle crée une autre activité. Ce comportement dépend du mode de lancement de l'activité défini dans le fichier manifeste, ainsi que des options et des indicateurs d'intent définis par l'entité qui lance l'activité. Pour en savoir plus, consultez la classe ActivityOptions
.
Lorsqu'une activité est déplacée vers un affichage secondaire, elle peut faire l'objet d'une mise à jour du contexte, du redimensionnement de la fenêtre, ainsi que de modifications de la configuration et des ressources. Si l'activité gère la modification de configuration, elle en est informée dans onConfigurationChanged()
. Sinon, elle est redémarrée.
Une activité doit vérifier l'affichage actuel dans onCreate()
et onConfigurationChanged()
si vous modifiez la configuration. Veillez à mettre à jour les ressources et la mise en page lorsque l'affichage change.
Si le mode de lancement sélectionné pour une activité autorise plusieurs instances, le lancement sur un écran secondaire peut créer une instance de l'activité. Les deux activités sont réactivées en même temps.
Vous pouvez également vous renseigner sur les API multi-écrans introduites dans Android 8.0.
Contexte d'activité ou d'application
L'utilisation du contexte adéquat est essentielle pour les campagnes multi-écrans. Lors de l'accès aux ressources, le contexte de l'activité (qui est affiché) est différent du contexte de l'application (qui ne l'est pas).
Le contexte d'activité contient des informations sur l'écran et est toujours ajusté en fonction de la zone d'affichage dans laquelle l'activité apparaît. Vous pouvez ainsi obtenir les bonnes informations sur les densités d'affichage ou les métriques de fenêtre de votre application. Vous devez toujours utiliser le contexte d'activité (ou un autre contexte basé sur l'UI) pour obtenir des informations sur la fenêtre ou l'écran actuels. Cela affecte également certaines API système qui utilisent des informations du contexte (voir la section Présentation des notifications toast).
La configuration de la fenêtre d'activité et l'affichage parent définissent les ressources et le contexte. Obtenez l'écran actuel comme suit :
Kotlin
val activityDisplay = activity.getDisplay()
Java
Display activityDisplay = activity.getDisplay();
Obtenez les métriques de la fenêtre d'activité actuelle :
Kotlin
val windowMetrics = activity.getWindowManager().getCurrentWindowMetrics()
Java
WindowMetrics windowMetrics = activity.getWindowManager().getCurrentWindowMetrics();
Obtenez les métriques de la fenêtre maximale pour la configuration système actuelle :
Kotlin
val maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics()
Java
WindowMetrics maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics();
Les métriques de la fenêtre maximale permettent de faire des calculs, des choix de mise en page ou de déterminer la taille des ressources à extraire à l'avance. Cette possibilité liée à onCreate()
vous permet de prendre ces décisions avant la première mise en page. Ces métriques ne doivent pas être utilisées pour disposer d'éléments de vue spécifiques. Utilisez plutôt les informations de l'objet Configuration
.
Encoches
Les pliables peuvent présenter une géométrie d'encoche différente selon qu'ils sont ouverts ou fermés. Pour éviter les problèmes liés aux encoches, consultez la section Assurer la compatibilité avec les encoches.
Écrans secondaires
Vous pouvez obtenir les affichages disponibles à partir du service système DisplayManager
:
Kotlin
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager val displays = displayManager.getDisplays()
Java
DisplayManager displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE); Display[] displays = displayManager.getDisplays();
Utilisez la classe Display
pour obtenir des informations sur un affichage particulier, comme sa taille ou ses indicateurs de sécurité.
Cependant, ne partez pas du principe que la taille d'affichage sera identique à celle de la zone d'affichage allouée à votre application. N'oubliez pas qu'en mode multifenêtre, votre application occupe une partie de l'écran.
Déterminez si une activité peut être lancée sur un écran :
Kotlin
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val activityAllowed = activityManager.isActivityStartAllowedOnDisplay(context, displayId, intent)
Java
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); boolean activityAllowed = activityManager.isActivityStartAllowedOnDisplay(context, displayId, intent);
Ensuite, lancez l'activité sur l'écran :
Kotlin
val options = ActivityOptions.makeBasic() options.setLaunchDisplayId(targetDisplay.displayId) startActivity(intent, options.toBundle())
Java
ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchDisplayId(targetDisplay.displayId); startActivity(intent, options.toBundle());
Compatibilité multi-écran
Android offre une compatibilité multi-écran pour les claviers, fonds d'écran et lanceurs de logiciels.
Clavier virtuel
Un clavier peut être affiché sur un écran secondaire si celui-ci est configuré pour accepter les décorations système. L'éditeur du mode de saisie apparaît automatiquement si un champ de texte demande la saisie de cet affichage.
Fond d'écran
Sous Android 10 (niveau d'API 29), les écrans secondaires peuvent comporter un fond d'écran. Le framework crée une instance WallpaperService.Engine
distincte pour chaque écran. Assurez-vous que la surface de chaque moteur est tracée indépendamment. Les développeurs peuvent charger des éléments à l'aide du contexte d'affichage dans WallpaperService.Engine#getDisplayContext()
. Assurez-vous également que votre fichier WallpaperInfo.xml
définit android:supportsMultipleDisplays="true"
.
Lanceurs d'applications
Une nouvelle catégorie de filtre d'intent, SECONDARY_HOME
, fournit une activité dédiée aux écrans secondaires. Les instances de l'activité sont utilisées sur tous les écrans compatibles avec les décorations système, à raison d'une par écran.
<activity>
...
<intent-filter>
<category android:name="android.intent.category.SECONDARY_HOME" />
...
</intent-filter>
</activity>
L'activité doit avoir un mode de lancement qui n'empêche pas plusieurs instances et qui peut s'adapter à différentes tailles d'écran. Le mode de lancement ne peut pas être singleInstance
ni singleTask
.
Par exemple, l'implémentation AOSP de Launcher3
accepte les activités SECONDARY_HOME
.
Métriques sur les fenêtres
Android 11 (niveau d'API 30) a introduit les méthodes WindowManager
suivantes afin de fournir les limites des applications exécutées en mode multifenêtre:
getCurrentWindowMetrics()
: renvoie un objetWindowMetrics
pour l'état de fenêtrage actuel du système.getMaximumWindowMetrics()
: renvoieWindowMetrics
pour le plus grand état de fenêtrage potentiel du système.
Les méthodes de bibliothèque Jetpack WindowManager computeCurrentWindowMetrics()
et computeMaximumWindowMetrics()
offrent des fonctionnalités similaires, mais rétrocompatibles avec le niveau d'API 14.
Pour obtenir des métriques relatives à des écrans autres que l'écran actuel, procédez comme suit (comme indiqué dans l'extrait de code):
- Créez un contexte d'affichage
- Créez un contexte de fenêtre pour l'affichage
- Récupérez l'instance
WindowManager
du contexte de fenêtre - Récupérez les métriques
WindowMetrics
de la zone d'affichage maximale disponible pour l'application
Kotlin
val windowMetrics = context.createDisplayContext(display) .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null) .getSystemService(WindowManager::class.java) .maximumWindowMetrics
Java
WindowMetrics windowMetrics = context.createDisplayContext(display) .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null) .getSystemService(WindowManager.class) .getMaximumWindowMetrics();
Méthodes obsolètes
Les méthodes Display
getSize()
et getMetrics()
ont été abandonnées au niveau d'API 30 en faveur des nouvelles méthodes WindowManager
.
Android 12 (niveau d'API 31) abandonne les méthodes Display
getRealSize()
et getRealMetrics()
, et adapte leur comportement pour correspondre plus précisément à celui de getMaximumWindowMetrics()
.
Configuration du mode multifenêtre
Si votre application cible Android 7.0 (niveau d'API 24) ou une version ultérieure, vous pouvez configurer la compatibilité de ses activités avec le mode multifenêtre. Vous pouvez définir des attributs dans votre fichier manifeste pour contrôler à la fois la taille et la mise en page. Les paramètres d'attribut d'une activité racine s'appliquent à toutes les activités de sa pile de tâches. Par exemple, si l'activité racine contient android:resizeableActivity="true"
, toutes les activités de la pile de tâches sont redimensionnables. Sur certains appareils plus grands, comme les Chromebook, votre application peut s'exécuter dans une fenêtre redimensionnable, même si vous spécifiez android:resizeableActivity="false"
. Si cela entraîne l'interruption de votre application, vous pouvez utiliser des filtres sur Google Play pour limiter sa disponibilité sur ces appareils.
Android 12 (niveau d'API 31) est défini par défaut sur le mode multifenêtre. Sur les grands écrans (classe de taille de fenêtre moyenne ou agrandie), toutes les applications s'exécutent en mode multifenêtre, quelle que soit la configuration. Sur les petits écrans, le système vérifie les éléments minWidth
, minHeight
et resizeableActivity
pour déterminer si l'activité peut s'exécuter en mode multifenêtre.
resizeableActivity
Définissez cet attribut dans l'élément <activity>
ou <application>
de votre fichier manifeste pour activer ou désactiver le mode multifenêtre jusqu'au niveau d'API 30:
<application
android:name=".MyActivity"
android:resizeableActivity=["true" | "false"] />;
Si cet attribut est défini sur true
, l'activité peut être lancée en mode Écran partagé et en mode Fenêtrage du bureau. Si l'attribut est défini sur false
, l'activité n'est pas compatible avec le mode multifenêtre. Si la valeur est "false" et que l'utilisateur tente de lancer l'activité en mode multifenêtre, l'activité s'affiche en plein écran.
Si votre application cible le niveau d'API 24 ou supérieur, mais que vous ne spécifiez pas de valeur pour cet attribut, cette valeur sera définie par défaut sur "true".
Si votre application cible le niveau d'API 31 ou supérieur, cet attribut fonctionne différemment sur les petits et les grands écrans:
- Grands écrans (classe de taille de fenêtre moyenne ou agrandie): toutes les applications sont compatibles avec le mode multifenêtre. L'attribut indique si une activité peut être redimensionnée. Si la valeur est
resizeableActivity="false"
, l'application passe en mode de compatibilité si nécessaire, conformément aux dimensions d'affichage. - Petits écrans (classe de taille de fenêtre compacte): si
resizeableActivity="true"
et que la largeur et la hauteur minimales de l'activité sont conformes aux exigences du mode multifenêtre, l'activité est compatible avec le mode multifenêtre. Si la valeur estresizeableActivity="false"
, l'activité n'accepte pas le mode multifenêtre, quelles que soient la largeur et la hauteur minimales.
supportsPictureInPicture
Définissez cet attribut dans le nœud <activity>
de votre fichier manifeste pour indiquer si l'activité est compatible avec le mode Picture-in-picture.
<activity
android:name=".MyActivity"
android:supportsPictureInPicture=["true" | "false"] />
configChanges
Pour gérer les modifications de la configuration multifenêtre, par exemple lorsqu'un utilisateur redimensionne une fenêtre, ajoutez l'attribut android:configChanges
au nœud <activity>
dans le fichier manifeste de votre application en utilisant au moins les valeurs suivantes:
<activity
android:name=".MyActivity"
android:configChanges="screenSize | smallestScreenSize
| screenLayout | orientation" />
Après avoir ajouté android:configChanges
, votre activité et vos fragments reçoivent un rappel onConfigurationChanged()
au lieu d'être détruits et recréés. Vous pouvez ensuite mettre à jour manuellement vos vues, actualiser les ressources et effectuer d'autres opérations si nécessaire.
<layout>
Sur Android 7.0 (niveau d'API 24) ou version ultérieure, l'élément manifeste <layout>
accepte plusieurs attributs qui affectent le comportement d'une activité en mode multifenêtre:
android:defaultHeight
,android:defaultWidth
: hauteur et largeur par défaut de l'activité lorsqu'elle est lancée en mode fenêtrage sur ordinateur.android:gravity
: emplacement initial de l'activité lorsqu'elle est lancée en mode fenêtrage pour ordinateur. Consultez la classeGravity
pour connaître les valeurs appropriées.android:minHeight
,android:minWidth
: hauteur et largeur minimales de l'activité dans les modes Écran partagé et Fenêtres de bureau. Si l'utilisateur déplace le séparateur en mode Écran partagé pour réduire une activité au minimum spécifié, le système recadre l'activité à la taille demandée par l'utilisateur.
Le code suivant montre comment spécifier la taille et l'emplacement par défaut d'une activité, ainsi que sa taille minimale lorsque l'activité est affichée en mode fenêtrage pour ordinateur:
<activity android:name=".MyActivity">
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end|..."
android:minHeight="450dp"
android:minWidth="300dp" />
</activity>
Mode multifenêtre au moment de l'exécution
À partir d'Android 7.0, le système propose des fonctionnalités compatibles avec les applications qui peuvent s'exécuter en mode multifenêtre.
Fonctionnalités désactivées en mode multifenêtre
En mode multifenêtre, Android peut désactiver ou ignorer les fonctionnalités qui ne s'appliquent pas à une activité qui partage l'écran de l'appareil avec d'autres activités ou applications.
En outre, certaines options de personnalisation de l'UI du système sont désactivées. Par exemple, les applications ne peuvent pas masquer la barre d'état si elles s'exécutent en mode multifenêtre (voir Contrôler la visibilité de l'UI du système).
Le système ignore les modifications apportées à l'attribut android:screenOrientation
.
Requêtes et rappels en mode multifenêtre
La classe Activity
propose les méthodes suivantes pour assurer la compatibilité avec le mode multifenêtre:
isInMultiWindowMode()
: indique si l'activité est en mode multifenêtre.isInPictureInPictureMode()
: indique si l'activité est en mode Picture-in-picture.onMultiWindowModeChanged()
: le système appelle cette méthode chaque fois que l'activité passe en mode multifenêtre ou sort de ce mode. Le système transmet à la méthode la valeur "true" si l'activité passe en mode multifenêtre, ou "false" si l'activité quitte le mode multifenêtre.onPictureInPictureModeChanged()
: le système appelle cette méthode chaque fois que l'activité passe en mode Picture-in-picture ou quitte ce mode. Le système transmet à la méthode la valeur "true" si l'activité passe en mode Picture-in-picture, ou "false" si l'activité quitte le mode Picture-in-picture.
La classe Fragment
expose les versions de la plupart de ces méthodes. (par exemple, Fragment.onMultiWindowModeChanged()
).
Mode Picture-in-picture
Pour mettre une activité en mode Picture-in-picture, appelez enterPictureInPictureMode()
. Cette méthode n'a aucun effet si l'appareil n'est pas compatible avec le mode Picture-in-picture. Pour en savoir plus, consultez Ajouter des vidéos en mode Picture-in-picture (PIP).
Nouvelles activités en mode multifenêtre
Lorsque vous lancez une nouvelle activité, vous pouvez indiquer qu'elle doit s'afficher à côté de l'activité actuelle, si possible. Utilisez l'indicateur d'intent FLAG_ACTIVITY_LAUNCH_ADJACENT
, qui demande au système d'essayer de créer la nouvelle activité dans une fenêtre adjacente afin que les deux activités partagent l'écran. Le système fera de son mieux, sans garantie de réussite.
Si un appareil est en mode fenêtrage de bureau et que vous lancez une nouvelle activité, vous pouvez spécifier les dimensions et la position de l'écran de la nouvelle activité en appelant ActivityOptions.setLaunchBounds()
. La méthode n'a aucun effet si l'appareil n'est pas en mode multifenêtre.
Au niveau d'API 30 et inférieur, si vous lancez une activité dans une pile de tâches, elle remplace l'activité à l'écran et hérite de toutes ses propriétés multifenêtres. Si vous souhaitez lancer la nouvelle activité dans une fenêtre distincte en mode multifenêtre, vous devez la lancer dans une nouvelle pile de tâches.
Android 12 (niveau d'API 31) permet aux applications de diviser la fenêtre de tâche d'une application entre plusieurs activités. Vous déterminez comment votre application affiche ses activités (plein écran, côte à côte ou empilées) en créant un fichier de configuration XML ou en effectuant des appels d'API Jetpack WindowManager.
Glisser-déposer
Les utilisateurs peuvent glisser-déposer des données d'une activité à l'autre pendant que les deux activités partagent l'écran. (Avant la version 7.0 d'Android, les utilisateurs ne pouvaient glisser-déposer des données qu'au cours d'une même activité.) Pour ajouter rapidement la compatibilité de l'acceptation du contenu supprimé, consultez l'API DropHelper
. Pour obtenir des conseils complets sur le glisser-déposer, consultez la section Activer le glisser-déposer.
Multi-instance
Chaque activité racine a sa propre tâche, qui s'affiche dans sa propre fenêtre. Pour lancer une nouvelle instance de votre application dans une fenêtre distincte, démarrez de nouvelles activités avec l'option FLAG_ACTIVITY_NEW_TASK
. Vous pouvez combiner ce paramètre à des attributs multifenêtres pour demander un emplacement spécifique pour la nouvelle fenêtre. Par exemple, une application de shopping peut afficher plusieurs fenêtres adjacentes pour comparer des produits.
Android 12 (niveau d'API 31) et versions ultérieures vous permettent de lancer deux instances d'une activité côte à côte dans la même fenêtre de tâche avec l'intégration d'activités.
Si vous souhaitez autoriser les utilisateurs à démarrer une autre instance de votre application à partir du lanceur d'applications ou de la barre des tâches, définissez android:resizeableActivity="true"
dans le fichier manifeste de votre activité de lanceur d'applications et n'utilisez pas de mode de lancement qui empêche plusieurs instances. Par exemple, une activité singleInstancePerTask
peut être instanciée plusieurs fois dans différentes tâches lorsque FLAG_ACTIVITY_MULTIPLE_TASK
ou FLAG_ACTIVITY_NEW_DOCUMENT
est défini.
Sur Android 15 (niveau d'API 35) ou version ultérieure, PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI
vous permet de déclarer la prise en charge de la multi-instance. La propriété est un signal explicite pour que l'UI du système expose des commandes à l'utilisateur afin de créer plusieurs instances de l'application. La propriété est indépendante du mode de lancement, mais ne doit être utilisée que lorsque le mode de lancement d'une activité ou d'une application est compatible avec la propriété, par exemple lorsque le mode de lancement n'est pas singleInstance
.
Lorsque plusieurs instances d'une application s'exécutent dans des fenêtres distinctes sur un appareil pliable, une ou plusieurs instances peuvent être mises en arrière-plan si la position de l'appareil change. Par exemple, supposons qu'un appareil soit déplié et que deux instances d'application s'exécutent dans des fenêtres distinctes de chaque côté de la ligne de flottaison. Si l'appareil est plié, l'une des instances peut être arrêtée au lieu d'essayer de remplir les fenêtres des deux instances sur un écran plus petit.
Validation du mode multifenêtre
Que votre application cible ou non le niveau d'API 24 ou supérieur, vous devez vérifier son comportement en mode multifenêtre si un utilisateur tente de le lancer en mode multifenêtre sur un appareil équipé d'Android 7.0 ou version ultérieure.
Appareils de test
Les appareils équipés d'Android 7.0 (niveau d'API 24) ou version ultérieure sont compatibles avec le mode multifenêtre.
Niveau d'API 23 ou inférieur
Lorsque les utilisateurs tentent d'afficher l'application en mode multifenêtre, le système la redimensionne de force, sauf si l'application déclare une orientation fixe.
Si votre application ne déclare pas d'orientation fixe, vous devez la lancer sur un appareil exécutant Android 7.0 ou version ultérieure, et essayer de passer l'application en mode Écran partagé. Vérifiez que l'expérience utilisateur est acceptable en cas de redimensionnement forcé de l'application.
Si l'application déclare une orientation fixe, vous devez essayer de passer en mode multifenêtre. Vérifiez que l'application reste en mode plein écran.
Niveaux d'API 24 à 30
Si votre application cible les niveaux d'API 24 à 30 et ne désactive pas la compatibilité multifenêtre, vérifiez le comportement suivant dans les modes Écran partagé et Fenêtrage pour ordinateur:
Ouvrez l'application en plein écran, puis passez en mode multifenêtre en appuyant de manière prolongée sur le bouton Récents. Vérifiez que l'application change de mode.
Lancez l'application directement en mode multifenêtre, puis vérifiez qu'elle se lance correctement. Pour lancer une application en mode multifenêtre, appuyez sur le bouton Applications récentes, puis appuyez de manière prolongée sur la barre de titre de votre application, puis faites-la glisser vers l'une des zones en surbrillance à l'écran.
Redimensionnez votre application en mode Écran partagé en faisant glisser le séparateur d'écran. Vérifiez que l'application est redimensionnée sans plantage et que les éléments d'interface nécessaires sont visibles.
Si vous avez spécifié des dimensions minimales pour votre application, essayez de redimensionner l'application afin que sa fenêtre soit plus petite que ces dimensions. Vérifiez que la taille de l'application ne dépasse pas les dimensions minimales spécifiées.
Lors de tous les tests, vérifiez que les performances de votre application sont acceptables. Par exemple, vérifiez que le délai avant la mise à jour de l'interface utilisateur n'est pas trop long une fois l'application redimensionnée.
Niveau d'API 31 ou supérieur
Si votre application cible le niveau d'API 31 ou supérieur, et que la largeur et la hauteur minimales de l'activité principale sont inférieures ou égales aux dimensions respectives de la zone d'affichage disponible, vérifiez tous les comportements recensés pour les niveaux d'API 24 à 30.
Checklist pour les tests
Pour vérifier les performances de votre application en mode multifenêtre, essayez les opérations suivantes. Vous devez essayer ces opérations en mode Écran partagé et en mode Fenêtrage du bureau, sauf indication contraire.
Activer et désactiver le mode multifenêtre
Passez de votre application à une autre et vérifiez qu'elle se comporte correctement tant qu'elle est visible, mais inactive. Par exemple, si votre application lit une vidéo, vérifiez que la lecture se poursuit pendant que l'utilisateur interagit avec une autre application.
En mode Écran partagé, essayez de déplacer le séparateur d'écran pour agrandir ou réduire votre application. Essayez ces opérations dans des configurations côte à côte et l'une au-dessus de l'autre. Vérifiez que l'application ne plante pas, que les fonctionnalités essentielles sont visibles et que l'opération de redimensionnement ne prend pas trop de temps.
Effectuez plusieurs opérations de redimensionnement à la suite. Assurez-vous que votre application ne plante pas ou ne libère pas de mémoire. Le service Memory Profiler d'Android Studio fournit des informations sur l'utilisation de la mémoire de votre application (consultez Inspecter l'utilisation de la mémoire de votre application avec Memory Profiler).
Utilisez votre application normalement dans plusieurs configurations de fenêtres, puis vérifiez qu'elle se comporte correctement. Vérifiez que le texte est lisible et que les éléments de l'interface utilisateur ne sont pas trop petits pour pouvoir interagir.
Compatibilité avec le mode multifenêtre désactivé
Aux niveaux d'API 24 à 30, si vous avez désactivé le mode multifenêtre en définissant android:resizeableActivity="false"
, vous devez lancer votre application sur un appareil équipé d'Android 7.0 à 11 et essayer de l'ouvrir dans les modes Écran partagé et Fenêtrage de bureau. Vérifiez que l'application reste en mode plein écran.
Ressources supplémentaires
Pour en savoir plus sur la fonctionnalité multifenêtre dans Android, consultez les articles suivants :
- Exemple d'application MultiWindowPlayground pour Android
Recommandations pour vous * Remarque: Le texte du lien s'affiche lorsque JavaScript est désactivé * Mode de compatibilité de l'appareil * Prendre en charge la redimensionnabilité des grands écrans * Gérer les modifications de configuration