Applications permanentes et mode ambiant du système

Ce guide explique comment rendre votre application toujours activée, comment réagir aux transitions d'état d'alimentation et comment gérer le comportement de l'application pour offrir une bonne expérience utilisateur tout en économisant la batterie.

Rendre une application constamment visible a un impact significatif sur l'autonomie de la batterie. Par conséquent, tenez-en compte lorsque vous ajoutez cette fonctionnalité.

Concepts clés

Lorsqu'une application Wear OS s'affiche en plein écran, elle se trouve dans l'un des deux états d'alimentation suivants :

  • Interactif : état de forte puissance où l'écran est à pleine luminosité, ce qui permet une interaction complète de l'utilisateur.
  • Veille : état de faible puissance où l'écran s'assombrit pour économiser de l'énergie. Dans cet état, l'interface utilisateur de votre application occupe toujours tout l'écran, mais le système peut modifier son apparence en la floutant ou en affichant du contenu en superposition, comme l'heure. On parle également de mode Veille.

Le système d'exploitation contrôle la transition entre ces états.

Une application toujours activée est une application qui affiche du contenu dans les états Interactif et Veille.

Lorsqu'une application toujours activée continue d'afficher sa propre interface utilisateur lorsque l'appareil est en état de faible puissance Veille, elle est décrite comme étant en mode ambiactif.

Transitions système et comportement par défaut

Lorsqu'une application est au premier plan, le système gère les transitions d'état d'alimentation en fonction de deux délais avant expiration déclenchés par l'inactivité de l'utilisateur.

  • Délai avant expiration 1 : état interactif à état Veille : après une période d'inactivité de l'utilisateur, l'appareil passe à l'état Veille.
  • Délai avant expiration 2 : retour au cadran : après une nouvelle période d'inactivité, le système peut masquer l'application en cours et afficher le cadran.

Immédiatement après que le système a effectué la première transition vers l'état Veille, le comportement par défaut dépend de la version de Wear OS et de la configuration de votre application :

  • Sur Wear OS 5 et versions antérieures, le système affiche une capture d'écran floutée de votre application mise en pause, avec l'heure superposée. Cet état est représenté par le nœud "AOD Lite" dans l'organigramme suivant.
  • Sur Wear OS 6 et versions ultérieures, si une application cible le SDK 36 ou une version ultérieure, elle est considérée comme toujours activée. L'écran est assombri, mais l'application continue de s'exécuter et reste visible. (Les mises à jour peuvent être aussi peu fréquentes qu'une fois par minute.) Cet état est représenté par le nœud "Global AOD" dans the l'organigramme suivant.

Personnaliser le comportement pour l'état Veille

Quel que soit le comportement par défaut du système, sur toutes les versions de Wear OS, vous pouvez personnaliser l'apparence ou le comportement de votre application en état Veille à l'aide de LocalAmbientModeManager pour observer les transitions d'état dans Jetpack Compose sur Wear OS. Cet état est représenté par le nœud "Mode ambiactif" dans l'organigramme suivant.

Observer l'état Veille

Pour réagir aux événements du mode Veille dans Jetpack Compose sur Wear OS :

  1. Utilisez LocalAmbientModeManager pour observer les modifications de l'état du mode Veille du système et ajuster vos composables en conséquence. Configurez votre composant pour qu'il s'adapte à un mode de faible puissance dans l'état AmbientMode.Ambient, puis restaurez-le sur un affichage interactif complet dans l'état AmbientMode.Interactive.

    // In a production application, the AmbientModeManager should be instantiated and provided at
    // the highest level of the Compose hierarchy (typically in the host Activity's setContent
    // block) using a CompositionLocalProvider. This ensures proper lifecycle management and
    // broad accessibility.
    
    // For this self-contained demo, AmbientModeManager is created and provided locally:
    val activityAmbientModeManager = rememberAmbientModeManager()
    CompositionLocalProvider(LocalAmbientModeManager provides activityAmbientModeManager) {
        val ambientModeManager = LocalAmbientModeManager.current
        val ambientMode = ambientModeManager?.currentAmbientMode
    
        if (ambientModeManager != null) {
            ambientModeManager.AmbientTickEffect {
                // While device is in ambient mode, update properties every minute or so
                // ...
            }
        }
    
        // ...
            val ambientModeName =
                when (ambientMode) {
                    is AmbientMode.Interactive -> "Interactive"
                    is AmbientMode.Ambient -> "Ambient"
                    else -> "Unknown"
                }
    
            Text(text = "$ambientModeName Mode")
            // ...
    }

Pour les développeurs qui utilisent Jetpack Compose, utilisez LocalAmbientModeManager, ce qui simplifie l'implémentation de ce modèle.

Organigramme du comportement en mode Veille

L'organigramme suivant illustre comment le système détermine le comportement en mode Veille en fonction de la version de Wear OS de l'appareil, de la targetSdkVersion de votre application et de l'implémentation ou non de AmbientLifecycleCallback.

Organigramme illustrant la logique de décision pour le mode ambiant Wear OS. Il montre comment la version de l'OS de l'appareil et la configuration de l'application déterminent l'un des trois résultats suivants : un calque flou, le mode Always-on Display global ou le mode Ambiactive géré par l'application.
Figure 1.: Organigramme illustrant la logique de décision pour le mode Veille de Wear OS.

Contrôler la durée d'activation de l'écran

Les sections suivantes décrivent comment gérer la durée d'affichage de votre application à l'écran.

Empêcher le retour au cadran avec une activité en cours ou une mise à jour en direct

Après un certain temps en état Veille (délai avant expiration 2), le système revient généralement au cadran. L'utilisateur peut configurer la durée du délai avant expiration dans les paramètres système. Dans certains cas d'utilisation, comme le suivi d'un entraînement par un utilisateur, une application peut avoir besoin de rester visible plus longtemps.

Sur Wear OS 5 et versions ultérieures, vous pouvez éviter cela en implémentant une activité en cours. Si votre application affiche des informations sur une tâche utilisateur en cours, comme une séance d'entraînement, vous pouvez utiliser l'API Ongoing Activity pour que votre application reste visible jusqu'à la fin de la tâche. Si un utilisateur revient manuellement au cadran, l'indicateur d'activité en cours lui permet de revenir à votre application en un seul geste.

Sur Wear OS 7 et versions ultérieures, vous pouvez également utiliser une mise à jour en direct à la place d'une activité en cours. Pour assurer la rétrocompatibilité, continuez à prendre en charge l'activité en cours sur les appareils exécutant Wear OS 6 ou une version antérieure.

Pour implémenter cela, l'intent tactile de la notification en cours doit pointer vers votre activité toujours activée, comme indiqué dans l'extrait de code suivant :

val activityIntent =
    Intent(this, AlwaysOnActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
    }

val pendingIntent =
    PendingIntent.getActivity(
        this,
        0,
        activityIntent,
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
    )

val notificationBuilder =
    NotificationCompat.Builder(this, CHANNEL_ID)
        // ...
        // ...
        .setOngoing(true)

// ...

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // ...
        // ...
        .setTouchIntent(pendingIntent)
        .build()

ongoingActivity.apply(applicationContext)

val notification = notificationBuilder.build()

Maintenir l'écran allumé et empêcher l'état Veille

Dans de rares cas, vous devrez peut-être empêcher complètement l'appareil de passer à l'état Veille. Autrement dit, pour éviter le délai avant expiration 1. Pour ce faire, vous pouvez utiliser le keepScreenOn modificateur. Il fonctionne comme un wakelock, en maintenant l'appareil à l'état Interactif. Utilisez-le avec une extrême prudence, car il a un impact important sur l'autonomie de la batterie.

Recommandations pour le mode Veille

Pour offrir la meilleure expérience utilisateur et économiser de l'énergie en mode Veille, suivez ces consignes de conception. Ces recommandations donnent la priorité à une expérience utilisateur claire, en évitant les informations trompeuses et en réduisant l'encombrement visuel, tout en optimisant la puissance d'affichage.

  • Réduisez l'encombrement visuel et la puissance d'affichage. Une interface utilisateur épurée et minimaliste indique à l'utilisateur que l'application est en état de faible puissance et économise beaucoup de batterie en limitant les pixels lumineux.
    • Maintenez au moins 85% de l'écran en noir.
    • N'affichez que les informations les plus importantes et déplacez les détails secondaires vers l'écran interactif.
    • Utilisez des contours pour les grandes icônes ou les boutons plutôt que des remplissages unis.
    • Évitez les grands blocs de couleur unie et les images de marque ou d'arrière-plan non fonctionnelles.
  • Gérez les données dynamiques obsolètes
    • Le rappel AmbientTickEffect n'est appelé que périodiquement (généralement une fois par minute) pour économiser de l'énergie. En raison de cette limitation, toutes les données qui changent fréquemment (comme un chronomètre, la fréquence cardiaque ou la distance parcourue lors d'un entraînement) deviennent obsolètes entre les mises à jour. Pour éviter d'afficher des informations trompeuses et incorrectes, remplacez ces valeurs en direct par du contenu d'espace réservé statique, tel que --.
  • Conservez une mise en page cohérente
    • Maintenez les éléments au même endroit dans les modes Interactif et Veille pour créer une transition fluide.
    • Affichez toujours l'heure.
  • Tenez compte du contexte
    • Si l'utilisateur se trouvait sur un écran de paramètres ou de configuration lorsque l'appareil est passé en mode Veille, envisagez d'afficher un écran plus pertinent de votre application au lieu de la vue des paramètres.
  • Gérez les exigences spécifiques à l'appareil
    • Dans l'objet AmbientMode renvoyé par currentAmbientMode :
      • Si isLowBitAmbientSupported est true, désactivez l'anticrénelage dans la mesure du possible.
      • Si isBurnInProtectionRequired est true, déplacez légèrement les éléments de l'interface utilisateur de manière périodique et évitez les zones blanches unies pour éviter le marquage de l'écran.

Débogage et test

Ces adb commandes peuvent être utiles lorsque vous développez ou testez le comportement de votre application lorsque l'appareil est en mode Veille :

# put device in ambient mode if the always on display is enabled in settings
# (and not disabled by other settings, such as theatre mode)
$ adb shell input keyevent KEYCODE_SLEEP

# put device in interactive mode
$ adb shell input keyevent KEYCODE_WAKEUP

Exemple : application d'entraînement

Prenons l'exemple d'une application d'entraînement qui doit afficher des métriques à l'utilisateur pendant toute la durée de sa séance d'exercice. L'application doit rester visible lors des transitions d'état Veille et ne pas être remplacée par le cadran.

Pour ce faire, le développeur doit procéder comme suit :

  1. Utilisez LocalAmbientModeManager pour gérer les modifications de l'interface utilisateur entre les états Interactif et Veille, par exemple en assombrissant l'écran et en supprimant les données non essentielles.
  2. Créez une nouvelle mise en page à faible consommation d'énergie pour l'état Veille qui suit les bonnes pratiques.
  3. Utilisez l'API Ongoing Activity (ou les mises à jour en direct sur Wear OS 7 et versions ultérieures) pendant toute la durée de l'entraînement pour empêcher le système de revenir au cadran.

Pour une implémentation complète, consultez l'exemple d'exercice basé sur Compose Exercise sample sur GitHub. Cet exemple montre également l'utilisation du LocalAmbientModeManager composable pour simplifier la gestion du mode Veille dans Compose.