Prise en charge des écrans connectés

Les écrans connectés étendent l'expérience de fenêtrage sur ordinateur aux téléphones standards, ce qui permet aux utilisateurs d'accéder à de grands écrans depuis leurs appareils mobiles. Cette fonctionnalité ouvre de nouvelles possibilités d'interaction avec les applications et de productivité des utilisateurs.

Toutes les fonctionnalités uniques de fenêtrage sur ordinateur s'appliquent aux écrans connectés. Lorsque vous connectez un téléphone à un écran, l'état du téléphone reste inchangé et une session de bureau vide démarre sur l'écran connecté. L'appareil et l'écran agissent comme deux systèmes individuels, avec des applications spécifiques à chaque écran.

Figure 1 : Téléphone connecté à un écran externe, avec une session de bureau sur l'écran tandis que le téléphone conserve son propre état.

Si vous connectez un appareil compatible avec le fenêtrage du bureau, comme une tablette, à un écran externe, la session de bureau s'étend sur les deux écrans. Les deux écrans fonctionnent alors comme un seul système continu. Cette configuration permet aux fenêtres, au contenu et au curseur de se déplacer librement entre les deux écrans.

Figure 2 : Tablette connectée à un écran externe, étendant la session de bureau sur les deux écrans.

Pour prendre en charge efficacement les écrans connectés, vous devez prêter attention à plusieurs aspects de la conception et de l'implémentation de votre application. Les bonnes pratiques suivantes permettent de garantir une expérience utilisateur fluide et productive.

Gérer les modifications d'affichage dynamique

De nombreuses applications sont conçues en partant du principe que l'objet Display et ses caractéristiques ne changeront pas au cours du cycle de vie de l'application. Toutefois, lorsqu'un utilisateur connecte ou déconnecte un moniteur externe, ou même déplace une fenêtre d'application entre les écrans, l'objet Display sous-jacent associé au contexte ou à la fenêtre de votre application peut changer. Les propriétés de l'écran, telles que la taille, la résolution, la fréquence d'actualisation, la compatibilité HDR et la densité, peuvent toutes être différentes. Si vous codez en dur des valeurs basées sur l'écran du téléphone, par exemple, vos mises en page risquent de ne pas fonctionner sur un écran externe.

Les densités de pixels des écrans externes peuvent également être très différentes. Vous devez vous assurer que votre application répond correctement aux modifications de densité. Cela implique d'utiliser des pixels indépendants de la densité (dp) pour les mises en page, de fournir des ressources spécifiques à la densité et de s'assurer que votre UI s'adapte correctement.

Si une activité est en cours d'exécution sur un écran externe lorsque celui-ci est déconnecté, le système la déplace vers l'écran principal. Le déplacement déclenche des modifications de configuration (taille et densité de l'écran, par exemple), qui peuvent entraîner la recréation de l'activité. Votre application doit gérer le changement de configuration en enregistrant et en restaurant l'état de l'UI pour éviter la perte de données ou une expérience utilisateur déroutante.

Utiliser le bon contexte

L'utilisation du contexte adéquat est essentielle dans les environnements 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 la densité d'affichage ou les métriques de fenêtre de votre application. Utilisez toujours 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.

Dans Jetpack Compose, vous pouvez accéder à des informations spécifiques à l'affichage à l'aide d'objets CompositionLocal tels que LocalConfiguration.current et LocalDensity.current. Lorsqu'une activité ou une fenêtre se déplace entre les écrans, la configuration de l'appareil change, ce qui déclenche une recomposition avec de nouvelles métriques d'affichage. Les objets CompositionLocal permettent à votre UI de s'adapter de manière fluide.

Obtenir des informations sur l'écran

Vous pouvez utiliser la classe Display pour obtenir des informations telles que la taille, la densité ou les indicateurs de l'écran. Utilisez le service système DisplayManager pour obtenir les affichages disponibles. Pour identifier les écrans externes, filtrez le Display.DEFAULT_DISPLAY, qui est généralement l'écran intégré du téléphone ou de la tablette :

val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }

Gérer le lancement et la configuration des activités

Avec les écrans connectés, les applications peuvent spécifier l'écran sur lequel elles doivent s'exécuter lorsqu'elles se lancent ou lorsqu'elles créent 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é.

Lorsqu'une activité est déplacée vers un écran secondaire, votre application 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, l'activité est redémarrée.

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, ce qui peut être utile pour certains scénarios multitâches.

Vous pouvez lancer une activité sur un écran particulier à l'aide de ActivityOptions. Notez que launchDisplayId nécessite Android 8 (niveau d'API 26) ou version ultérieure.

// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
    .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
    ?.displayId

// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
    val intent = Intent(this, MySecondaryActivity::class.java)
    val options = ActivityOptions.makeBasic()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        options.launchDisplayId = externalDisplayId
    }
    startActivity(intent, options.toBundle())
} else {
    // Optionally, handle the case where no external display is connected.
}

Éviter les listes d'autorisation d'appareils

Les applications limitent parfois l'UI et les fonctionnalités pour grands écrans à certains appareils via une liste d'autorisation ou en vérifiant BUILD.MODEL et la taille d'affichage intégrée. Cette approche n'est pas efficace pour les écrans connectés, car pratiquement n'importe quel appareil peut être connecté à un grand écran, et le modèle d'appareil ne change pas lorsqu'un écran externe est connecté.

Au lieu d'utiliser des listes d'autorisation ou de vérifier BUILD.MODEL et la taille d'affichage intégrée, vérifiez les métriques de fenêtre ou les fonctionnalités de l'appareil au moment de l'exécution pour prendre des décisions concernant l'UI. Utilisez les API Jetpack WindowManager ou les classes de taille de fenêtre pour créer des mises en page responsives et adaptatives pour différentes tailles et densités d'écran.

Compatibilité avec les périphériques externes

Lorsque les utilisateurs se connectent à un écran externe, ils créent souvent un environnement plus semblable à celui d'un ordinateur de bureau. Cela implique souvent d'utiliser des claviers, des souris, des trackpads, des webcams, des micros et des haut-parleurs externes. Vous devez vous assurer que votre application fonctionne parfaitement avec ces périphériques. Cela inclut la gestion des raccourcis clavier, la gestion des interactions avec le pointeur de la souris, la prise en charge correcte des caméras ou microphones externes, et le respect du routage de la sortie audio. Pour en savoir plus, consultez Entrées compatibles sur les grands écrans.

Améliorer la productivité des utilisateurs

Les écrans connectés offrent une excellente opportunité d'améliorer la productivité des utilisateurs. Vous disposez désormais des outils nécessaires pour créer des applications mobiles offrant des expériences comparables à celles des applications pour ordinateur. Envisagez d'implémenter les fonctionnalités suivantes pour améliorer la productivité des utilisateurs :

  • Autorisez les utilisateurs à ouvrir plusieurs instances de la même application. Cette fonctionnalité est très utile pour comparer des documents, gérer différentes conversations ou afficher plusieurs fichiers simultanément.
  • Permettez aux utilisateurs de partager des données enrichies dans et en dehors de votre application grâce au glisser-déposer.
  • Aidez les utilisateurs à maintenir leur workflow lors des modifications de configuration en implémentant un système de gestion de l'état robuste.

En suivant ces consignes et en utilisant les exemples de code fournis, vous pouvez créer des applications qui s'adaptent de manière fluide aux écrans connectés, offrant aux utilisateurs une expérience plus riche et plus productive.