Wear OS gère automatiquement le passage en mode économie d'énergie pour une application active lorsqu'un utilisateur n'utilise plus sa montre. Il s'agit du mode Veille du système. Si l'utilisateur interagit de nouveau avec la montre dans un certain délai, Wear OS lui permet de revenir à l'application qu'il a quittée.
Dans des cas d'utilisation spécifiques, par exemple lorsqu'un utilisateur souhaite consulter sa fréquence cardiaque et son allure pendant une course, vous pouvez également contrôler le contenu affiché en mode économie d'énergie (mode Veille). Les applications Wear OS qui s'exécutent en mode Veille et en mode interactif sont les applications toujours activées.
Rendre une application constamment visible a un impact sur l'autonomie de la batterie. Par conséquent, tenez-en compte lorsque vous ajoutez cette fonctionnalité à votre application.
Configurer votre projet
Pour prendre en charge le mode Veille, procédez comme suit :
- Créez ou mettez à jour votre projet en fonction des configurations de la page Créer et exécuter une appli connectée.
- Ajoutez l'autorisation
WAKE_LOCK
au fichier manifeste Android :
<uses-permission android:name="android.permission.WAKE_LOCK" />
Mode Veille avec la classe "AmbientModeSupport"
Pour utiliser la classe AmbientModeSupport
, procédez comme suit :
-
Créez une sous-classe d'
FragmentActivity
ou l'une de ses sous-classes. -
Implémentez l'interface
AmbientCallbackProvider
, comme dans l'exemple suivant. Ignorez la méthodegetAmbientCallback()
pour fournir les rappels nécessaires permettant de réagir aux événements de veille du système Android. Vous créerez la classe de rappel personnalisée ultérieurement.Kotlin
class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { ... override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback = MyAmbientCallback() ... }
Java
public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { ... @Override public AmbientModeSupport.AmbientCallback getAmbientCallback() { return new MyAmbientCallback(); } ... }
-
Dans la méthode
onCreate()
, activez le mode Veille en appelantAmbientModeSupport.attach(FragmentActivity)
. Cette méthode renvoie unAmbientModeSupport.AmbientController
. Le contrôleur vous permet de vérifier l'état de veille en dehors des rappels. Vous pouvez conserver une référence à l'objetAmbientModeSupport.AmbientController
:Kotlin
class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { ... /* * Declare an ambient mode controller, which will be used by * the activity to determine if the current mode is ambient. */ private lateinit var ambientController: AmbientModeSupport.AmbientController ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... ambientController = AmbientModeSupport.attach(this) } ... }
Java
public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { ... /* * Declare an ambient mode controller, which will be used by * the activity to determine if the current mode is ambient. */ private AmbientModeSupport.AmbientController ambientController; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... ambientController = AmbientModeSupport.attach(this); } ... }
-
Créez une classe interne qui étend la classe
AmbientCallback
afin d'agir sur les événements de veille. Cette classe deviendra l'objet renvoyé par la méthode que vous avez créée à l'étape 2, comme illustré dans l'exemple suivant :Kotlin
private class MyAmbientCallback : AmbientModeSupport.AmbientCallback() { override fun onEnterAmbient(ambientDetails: Bundle?) { // Handle entering ambient mode } override fun onExitAmbient() { // Handle exiting ambient mode } override fun onUpdateAmbient() { // Update the content } }
Java
private class MyAmbientCallback extends AmbientModeSupport.AmbientCallback { @Override public void onEnterAmbient(Bundle ambientDetails) { // Handle entering ambient mode } @Override public void onExitAmbient() { // Handle exiting ambient mode } @Override public void onUpdateAmbient() { // Update the content } }
Consultez l'exemple AlwaysOnKotlin sur GitHub pour en savoir plus et découvrir les bonnes pratiques.
Mode Veille avec la classe "WearableActivity"
Pour les nouveaux projets et les projets existants, vous pouvez ajouter une prise en charge du mode Veille à votre application Wear en mettant à jour la configuration de votre projet.
Créer une activité compatible avec le mode Veille
Vous pouvez activer le mode Veille dans votre activité à l'aide de la classe
WearableActivity
comme suit :
- Créez une activité qui étend
WearableActivity
. - Dans la méthode
onCreate()
de votre activité, appelez la méthodesetAmbientEnabled()
.
L'extrait de code suivant montre comment activer le mode Veille dans une activité :
Kotlin
class MainActivity : WearableActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setAmbientEnabled() ... } }
Java
public class MainActivity extends WearableActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setAmbientEnabled(); ... }
Gérer les transitions entre les modes
Si l'utilisateur n'interagit pas avec votre application pendant un certain temps, alors que celle-ci est affichée, ou si l'écran est recouvert, le système fait passer l'activité en mode Veille.
Une fois que l'application passe en mode Veille, mettez à jour l'interface utilisateur des activités avec une mise en page plus basique afin de réduire la consommation d'énergie. Utilisez un arrière-plan noir avec un minimum d'éléments graphiques et de textes blancs.
Pour faciliter la transition du mode interactif au mode Veille, essayez de conserver une disposition similaire des éléments à l'écran.
Remarque : En mode Veille, désactivez tous les éléments interactifs à l'écran, tels que les boutons.
Lorsque l'activité passe en mode Veille, le système appelle la méthode onEnterAmbient()
de votre rappel de veille. L'extrait de code suivant indique comment changer la couleur du texte en blanc et désactiver l'anticrénelage après le passage du système en mode Veille :
Kotlin
override fun onEnterAmbient(ambientDetails: Bundle?) { super.onEnterAmbient(ambientDetails) stateTextView.setTextColor(Color.WHITE) stateTextView.paint.isAntiAlias = false }
Java
@Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); stateTextView.setTextColor(Color.WHITE); stateTextView.getPaint().setAntiAlias(false); }
Lorsque l'utilisateur appuie sur l'écran ou lève son poignet, l'activité repasse du mode Veille au mode interactif. Le système appelle la méthode onExitAmbient()
. Ignorez cette méthode pour actualiser la mise en page de l'interface utilisateur afin que votre application s'affiche en couleur et passe en mode interactif.
L'extrait de code suivant indique comment changer la couleur du texte en vert et activer l'anticrénelage après le passage du système en mode interactif :
Kotlin
override fun onExitAmbient() { super.onExitAmbient() stateTextView.setTextColor(Color.GREEN) stateTextView.paint.isAntiAlias = true }
Java
@Override public void onExitAmbient() { super.onExitAmbient(); stateTextView.setTextColor(Color.GREEN); stateTextView.getPaint().setAntiAlias(true); }
Actualiser le contenu en mode Veille
Le mode Veille vous permet d'actualiser l'écran avec de nouvelles informations pour l'utilisateur, mais vous devez trouver le juste équilibre entre l'actualisation de l'affichage et l'autonomie de la batterie. En mode Veille, actualisez l'écran une fois par minute maximum.
Pour actualiser le contenu de l'application, ignorez la méthode
onUpdateAmbient()
dans le rappel de veille :
Kotlin
override fun onUpdateAmbient() { super.onUpdateAmbient() // Update the content }
Java
@Override public void onUpdateAmbient() { super.onUpdateAmbient(); // Update the content }
Il est déconseillé d'actualiser une application Wear OS en mode Veille plus d'une fois par minute. Pour les applications qui nécessitent des actualisations plus fréquentes, utilisez un objet AlarmManager
afin d'activer le processeur et d'actualiser l'écran plus fréquemment.
Pour implémenter une alarme qui actualise le contenu plus fréquemment en mode Veille, procédez comme suit :
- Préparez le gestionnaire d'alarmes.
- Définissez la fréquence des actualisations.
- Vérifiez si l'appareil est actuellement en mode Veille et programmez la prochaine actualisation lorsque l'activité passera en mode Veille.
- Annulez l'alarme lorsque l'activité passe en mode interactif ou lorsque l'activité est arrêtée.
Remarque : Le gestionnaire d'alarmes peut créer des instances de votre activité à mesure qu'elles sont déclenchées. Pour éviter ce comportement, déclarez votre activité à l'aide du paramètre android:launchMode="singleInstance"
dans le fichier manifeste.
Les sections suivantes décrivent ces étapes en détail.
Préparer le gestionnaire d'alarmes
Le gestionnaire d'alarmes lance un PendingIntent
qui actualise l'écran et planifie l'alarme suivante. L'exemple suivant montre comment déclarer le gestionnaire d'alarmes et l'intent en attente dans la méthode onCreate()
de votre activité :
Kotlin
// Action for updating the display in ambient mode, per our custom refresh cycle private const val AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE" ... private lateinit var ambientUpdateAlarmManager: AlarmManager private lateinit var ambientUpdatePendingIntent: PendingIntent private lateinit var ambientUpdateBroadcastReceiver: BroadcastReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setAmbientEnabled() ambientUpdateAlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager ambientUpdatePendingIntent = Intent(AMBIENT_UPDATE_ACTION).let { ambientUpdateIntent -> PendingIntent.getBroadcast(this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT) } ambientUpdateBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { refreshDisplayAndSetNextUpdate() } } ... }
Java
// Action for updating the display in ambient mode, per our custom refresh cycle private static final String AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE"; private AlarmManager ambientUpdateAlarmManager; private PendingIntent ambientUpdatePendingIntent; private BroadcastReceiver ambientUpdateBroadcastReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setAmbientEnabled(); ambientUpdateAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent ambientUpdateIntent = new Intent(AMBIENT_UPDATE_ACTION); ambientUpdatePendingIntent = PendingIntent.getBroadcast( this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT); ambientUpdateBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { refreshDisplayAndSetNextUpdate(); } }; ... }
Enregistrez et annulez l'enregistrement du broadcast receiver à l'aide de onResume()
et de onPause()
:
Kotlin
override fun onResume() { super.onResume() IntentFilter(AMBIENT_UPDATE_ACTION).also { filter -> registerReceiver(ambientUpdateBroadcastReceiver, filter) } } override fun onPause() { super.onPause() unregisterReceiver(ambientUpdateBroadcastReceiver) ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) }
Java
@Override public void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(AMBIENT_UPDATE_ACTION); registerReceiver(ambientUpdateBroadcastReceiver, filter); ... } @Override public void onPause() { super.onPause(); unregisterReceiver(ambientUpdateBroadcastReceiver); ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); ... }
Actualiser l'écran et planifier des mises à jour de données
Dans cet exemple d'activité, le gestionnaire d'alarmes se déclenche toutes les 20 secondes en mode Veille. Lorsque le minuteur se déclenche, l'alarme déclenche l'intent pour actualiser l'écran, puis définit le délai pour la prochaine actualisation.
L'exemple suivant montre comment actualiser les informations à l'écran et définir l'alarme pour la prochaine actualisation :
Kotlin
// Milliseconds between waking processor/screen for updates private val AMBIENT_INTERVAL_MS: Long = TimeUnit.SECONDS.toMillis(20) ... private fun refreshDisplayAndSetNextUpdate() { if (isAmbient) { // Implement data retrieval and update the screen for ambient mode } else { // Implement data retrieval and update the screen for interactive mode } val timeMs: Long = System.currentTimeMillis() // Schedule a new alarm if (isAmbient) { // Calculate the next trigger time val delayMs: Long = AMBIENT_INTERVAL_MS - timeMs % AMBIENT_INTERVAL_MS val triggerTimeMs: Long = timeMs + delayMs ambientUpdateAlarmManager.setExact( AlarmManager.RTC_WAKEUP, triggerTimeMs, ambientUpdatePendingIntent) } else { // Calculate the next trigger time for interactive mode } }
Java
// Milliseconds between waking processor/screen for updates private static final long AMBIENT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20); private void refreshDisplayAndSetNextUpdate() { if (isAmbient()) { // Implement data retrieval and update the screen for ambient mode } else { // Implement data retrieval and update the screen for interactive mode } long timeMs = System.currentTimeMillis(); // Schedule a new alarm if (isAmbient()) { // Calculate the next trigger time long delayMs = AMBIENT_INTERVAL_MS - (timeMs % AMBIENT_INTERVAL_MS); long triggerTimeMs = timeMs + delayMs; ambientUpdateAlarmManager.setExact( AlarmManager.RTC_WAKEUP, triggerTimeMs, ambientUpdatePendingIntent); } else { // Calculate the next trigger time for interactive mode } }
Planifier la prochaine alarme
Planifiez l'alarme pour actualiser l'écran en ignorant les méthodes onEnterAmbient()
et onUpdateAmbient()
, comme illustré dans l'exemple suivant :
Kotlin
override fun onEnterAmbient(ambientDetails: Bundle?) { super.onEnterAmbient(ambientDetails) refreshDisplayAndSetNextUpdate() } override fun onUpdateAmbient() { super.onUpdateAmbient() refreshDisplayAndSetNextUpdate() }
Java
@Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); refreshDisplayAndSetNextUpdate(); } @Override public void onUpdateAmbient() { super.onUpdateAmbient(); refreshDisplayAndSetNextUpdate(); }
Remarque : Dans cet exemple, la méthode refreshDisplayAndSetNextUpdate()
est appelée chaque fois que l'écran doit être actualisé. Pour d'autres exemples indiquant quand appeler cette méthode, consultez l'exemple AlwaysOnKotlin sur GitHub.
Annuler l'alarme
Lorsque l'appareil passe en mode interactif, annulez l'alarme dans la méthode onExitAmbient()
:
Kotlin
override fun onExitAmbient() { super.onExitAmbient() ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) }
Java
@Override public void onExitAmbient() { super.onExitAmbient(); ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); }
Lorsque l'utilisateur quitte ou arrête votre activité, annulez l'alarme dans la méthode onDestroy()
de votre activité :
Kotlin
override fun onDestroy() { ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent) super.onDestroy() }
Java
@Override public void onDestroy() { ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent); super.onDestroy(); }