Services Santé propose une assistance de premier ordre pour les applications d'entraînement via ExerciseClient
.
Avec ExerciseClient
, votre application peut contrôler quand un exercice est en cours, ajouter des objectifs et obtenir des informations sur l'état de l'exercice, sur les événements d'exercice ou sur d'autres métriques souhaitées. Pour en savoir plus, consultez la liste complète des types d'exercices pris en charge par Services Santé.
Consultez le Exemple d'exercice sur GitHub.
Ajouter des dépendances
Pour ajouter une dépendance à Services Santé, vous devez ajouter le dépôt Maven de Google à votre projet. Pour en savoir plus, consultez les informations sur le dépôt Maven de Google.
Ensuite, dans le fichier build.gradle
, au niveau du module, ajoutez la dépendance suivante :
Groovy
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha04" }
Kotlin
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha04") }
Structure de l'application
Utilisez la structure d'application suivante lorsque vous créez une application d'exercice avec Services Santé :
- Conservez vos écrans et la navigation au sein d'une activité principale.
- Gérez l'état de l'entraînement, les données des capteurs, l'activité en cours et les données avec un service de premier plan.
- Stockez des données avec Room et utilisez WorkManager pour importer des données.
Lors de la préparation d'un entraînement et pendant l'entraînement, votre activité peut être arrêtée pour plusieurs raisons. L'utilisateur peut passer à une autre application ou revenir au cadran. Le système peut afficher un élément par-dessus votre activité ou l'écran peut s'éteindre après une période d'inactivité.
Utilisez un ForegroundService
en continu avec ExerciseClient
pour garantir le bon fonctionnement de l'ensemble de l'entraînement.
L'utilisation d'un ForegroundService
vous permet d'utiliser l'API Ongoing Activity pour afficher un indicateur sur les surfaces de votre montre, ce qui permet à l'utilisateur de revenir rapidement à l'entraînement.
Il est essentiel que vous demandiez les données de localisation de manière appropriée dans votre service de premier plan. Dans votre fichier manifeste, spécifiez le service de premier plan nécessaire types et autorisations:
<manifest ...> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application ...> <!-- If your app is designed only for devices that run Wear OS 4 or lower, use android:foregroundServiceType="location" instead. --> <service android:name=".MyExerciseSessionRecorder" android:foregroundServiceType="health|location"> </service> </application> </manifest>
Utilisez AmbientLifecycleObserver
pour l'activité de pré-entraînement, qui contient l'appel prepareExercise()
, et pour votre activité d'entraînement. Cependant, ne mettez pas à jour l'affichage pendant l'entraînement en mode Bruit ambiant : Services Santé regroupe les données d'entraînement lorsque l'écran de l'appareil est en mode Bruit ambiant pour économiser de l'énergie. Les informations affichées peuvent donc ne pas être récentes. Pendant les entraînements, affichez des données pertinentes pour l'utilisateur, avec des informations à jour ou un écran vide.
Vérifier les fonctionnalités
Chaque ExerciseType
accepte certains types de données pour les métriques et les objectifs d'exercice. Vérifiez ces fonctionnalités au démarrage, car elles peuvent varier en fonction de l'appareil. Par exemple, certains appareils ne prendront pas en charge un type d'exercice ou une fonction spécifique, comme la mise en pause automatique. De plus, les fonctionnalités d'un appareil peuvent changer au fil du temps, avec une mise à jour logicielle par exemple.
Au démarrage de l'application, interrogez les fonctionnalités de l'appareil, puis stockez et traitez les éléments suivants :
- Les exercices pris en charge par la plate-forme
- Les fonctionnalités prises en charge pour chaque exercice
- Les types de données pris en charge pour chaque exercice
- Les autorisations requises pour chacun de ces types de données
Utilisez ExerciseCapabilities.getExerciseTypeCapabilities()
avec le type d'exercice souhaité pour voir le type de métriques que vous pouvez demander, les objectifs d'exercice que vous pouvez configurer et les autres fonctionnalités disponibles pour ce type. Ce processus est illustré dans l'exemple suivant :
val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
val capabilities = exerciseClient.getCapabilitiesAsync().await()
if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
runningCapabilities =
capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
}
}
Dans le fichier ExerciseTypeCapabilities
renvoyé, supportedDataTypes
répertorie les types de données pour lesquels vous pouvez demander des données. Cela varie selon l'appareil. Veillez donc à ne pas demander de DataType
non compatible. Sinon, votre requête pourrait échouer.
Utilisez les champs supportedGoals
et supportedMilestones
pour déterminer si l'exercice peut prendre en charge un objectif d'exercice que vous souhaitez créer.
Si votre application autorise l'utilisateur à utiliser la mise en pause automatique, vous devez vérifier que cette fonctionnalité est compatible avec l'appareil à l'aide de supportsAutoPauseAndResume
.
ExerciseClient
refusera les requêtes non compatibles avec l'appareil.
L'exemple suivant vérifie la prise en charge du type de données HEART_RATE_BPM
, la fonctionnalité d'objectif STEPS_TOTAL
et la fonctionnalité de mise en pause automatique :
// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes
// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals =
(stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)
// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume
Demander à recevoir des informations sur l'état de l'exercice
Les mises à jour sur l'exercice sont transmises à un écouteur. Votre application ne peut enregistrer qu'un seul écouteur à la fois. Configurez votre écouteur avant de commencer l'entraînement, comme illustré dans l'exemple suivant. Votre écouteur ne reçoit que des informations sur les exercices de votre application.
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
val exerciseStateInfo = update.exerciseStateInfo
val activeDuration = update.activeDurationCheckpoint
val latestMetrics = update.latestMetrics
val latestGoals = update.latestAchievedGoals
}
override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
// For ExerciseTypes that support laps, this is called when a lap is marked.
}
override fun onAvailabilityChanged(
dataType: DataType<*, *>,
availability: Availability
) {
// Called when the availability of a particular DataType changes.
when {
availability is LocationAvailability -> // Relates to Location/GPS.
availability is DataTypeAvailability -> // Relates to another DataType.
}
}
}
exerciseClient.setUpdateCallback(callback)
Gérer la durée de vie de l'exercice
Services Santé prend en charge au maximum un exercice à la fois pour toutes les applications de l'appareil. Si le suivi d'un exercice est en cours et qu'une autre application démarre le suivi d'un nouvel exercice, le suivi du premier est arrêté.
Avant de commencer l'exercice, procédez comme suit :
- Vérifier si un exercice est déjà en cours de suivi et réagir en conséquence. Par exemple, l'application peut demander confirmation à l'utilisateur avant d'abandonner un exercice pour commencer à en suivre un nouveau.
L'exemple suivant montre comment vérifier un exercice existant avec getCurrentExerciseInfoAsync
:
lifecycleScope.launch {
val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
when (exerciseInfo.exerciseTrackedStatus) {
OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
}
}
Autorisations
Lorsque vous utilisez ExerciseClient
, assurez-vous que votre application demande et gère le
autorisations nécessaires.
Si votre appli utilise des données LOCATION
, assurez-vous qu'elle demande et gère le
les autorisations appropriées
pour cela également.
Pour tous les types de données, avant d'appeler prepareExercise()
ou startExercise()
, procédez comme suit :
- Spécifiez les autorisations appropriées pour les types de données demandés dans le fichier
AndroidManifest.xml
. - Vérifiez que l'utilisateur a accordé les autorisations nécessaires. Pour en savoir plus, consultez la section Exiger des autorisations d'applications. Services Santé rejette la requête si les autorisations nécessaires ne sont pas déjà accordées.
Pour les données de localisation, procédez comme suit :
- Vérifiez que le GPS est activé sur l'appareil à l'aide d'
isProviderEnabled(LocationManager.GPS_PROVIDER)
. Invitez l'utilisateur à ouvrir les paramètres de localisation. si nécessaire. - Assurez-vous qu'un
ForegroundService
avec leforegroundServiceType
approprié est conservé tout au long de l'entraînement.
Se préparer pour un entraînement
Certains capteurs, tels que le GPS ou la fréquence cardiaque, peuvent prendre un peu de temps pour être prêts, ou l'utilisateur peut vouloir consulter ses données avant de commencer son entraînement. La méthode facultative prepareExerciseAsync()
permet à ces capteurs de se mettre en marche et de recevoir des données sans démarrer le minuteur de l'entraînement. La activeDuration
n'est pas affectée par cette durée de préparation.
Avant d'appeler prepareExerciseAsync()
, procédez comme suit :
Vérifiez le paramètre de localisation à l'échelle de la plate-forme. L'utilisateur contrôle ce paramètre dans le menu principal des paramètres. Ce paramètre est différent de la vérification des autorisations au niveau de l'application.
Si le paramètre est désactivé, informez l'utilisateur qu'il a refusé l'accès à la localisation et invitez-le à l'activer si votre application a besoin de la localisation.
Vérifiez que votre application dispose des autorisations d'exécution pour les capteurs corporels, la reconnaissance de l'activité et la géolocalisation précise. Pour les autorisations manquantes, demandez à l'utilisateur des autorisations d'exécution fournissant un contexte approprié. Si l'utilisateur n'accorde pas d'autorisation spécifique, supprimez les types de données associés à l'autorisation de l'appel à
prepareExerciseAsync()
. Si aucune autorisation concernant le capteur corporel ou la localisation n'est accordée, n'appelez pasprepareExerciseAsync()
, car l'appel de préparation est destiné spécifiquement à acquérir une fréquence cardiaque ou une position GPS stable avant de commencer un exercice. L'application peut toujours obtenir la distance, le rythme, la vitesse et d'autres métriques basées sur les pas qui ne nécessitent pas ces autorisations.
Procédez comme suit pour vous assurer que votre appel à prepareExerciseAsync()
aboutit :
- Utilisez
AmbientLifecycleObserver
pour l'activité de pré-entraînement qui contient l'appel de préparation. - Appelez
prepareExerciseAsync()
depuis votre service de premier plan. S'il n'est pas en service et qu'il est lié au cycle de vie de l'activité, la préparation du capteur risque d'être inutilement interrompue. - Appelez
endExercise()
pour désactiver les capteurs et réduire la consommation d'énergie si l'utilisateur quitte l'activité précédant l'entraînement.
L'exemple suivant montre comment appeler prepareExerciseAsync()
:
val warmUpConfig = WarmUpConfig(
ExerciseType.RUNNING,
setOf(
DataType.HEART_RATE_BPM,
DataType.LOCATION
)
)
// Only necessary to call prepareExerciseAsync if body sensor or location
//permissions are given
exerciseClient.prepareExerciseAsync(warmUpConfig).await()
// Data and availability updates are delivered to the registered listener.
Une fois que l'application est à l'état PREPARING
, les informations sur la disponibilité des capteurs sont transmises entre ExerciseUpdateCallback
et onAvailabilityChanged()
.
Ces informations peuvent ensuite être présentées à l'utilisateur pour qu'il puisse décider s'il souhaite commencer son entraînement.
Commencer l'entraînement
Lorsque vous souhaitez commencer un exercice, créez une ExerciseConfig
pour configurer le type d'exercice, les types de données pour lesquels vous souhaitez recevoir des métriques, ainsi que les objectifs ou les jalons de l'exercice.
Les objectifs d'exercice sont constitués d'un DataType
et d'une condition. Les objectifs d'exercice sont ponctuels et sont déclenchés lorsqu'une condition est remplie (par exemple, lorsque l'utilisateur parcourt une certaine distance). Vous pouvez également définir un jalon d'exercice, qui se déclenchera plusieurs fois, par exemple chaque fois que l'utilisateur parcourra un certain nombre de kilomètres au-delà de la distance définie.
L'exemple suivant montre comment créer un objectif de chaque type :
const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters
suspend fun startExercise() {
// Types for which we want to receive metrics.
val dataTypes = setOf(
DataType.HEART_RATE_BPM,
DataType.CALORIES_TOTAL,
DataType.DISTANCE
)
// Create a one-time goal.
val calorieGoal = ExerciseGoal.createOneTimeGoal(
DataTypeCondition(
dataType = DataType.CALORIES_TOTAL,
threshold = CALORIES_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
)
)
// Create a milestone goal. To make a milestone for every kilometer, set the initial
// threshold to 1km and the period to 1km.
val distanceGoal = ExerciseGoal.createMilestone(
condition = DataTypeCondition(
dataType = DataType.DISTANCE_TOTAL,
threshold = DISTANCE_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
),
period = DISTANCE_THRESHOLD
)
val config = ExerciseConfig(
exerciseType = ExerciseType.RUNNING,
dataTypes = dataTypes,
isAutoPauseAndResumeEnabled = false,
isGpsEnabled = true,
exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
)
exerciseClient.startExerciseAsync(config).await()
}
Vous pouvez également compter les tours pour tous les exercices. Services Santé fournit un
ExerciseLapSummary
avec des métriques agrégées sur la durée des tours.
L'exemple précédent montre l'utilisation de isGpsEnabled
, qui doit être défini sur true lors de la requête de données de localisation. Cependant, l'utilisation du GPS peut aussi vous aider pour d'autres métriques.
Si ExerciseConfig
spécifie la distance en tant que DataType
, le nombre de pas est utilisé par défaut pour estimer la distance. Si vous activez le GPS, vous pouvez utiliser les informations de localisation pour estimer la distance.
Interrompre, reprendre et terminer un entraînement
Vous pouvez suspendre, reprendre et arrêter des entraînements à l'aide de la méthode appropriée, telle que pauseExerciseAsync()
ou endExerciseAsync()
.
Utilisez l'état issu de ExerciseUpdate
comme source de référence. L'entraînement n'est pas considéré comme suspendu lorsque l'appel à pauseExerciseAsync()
est renvoyé, mais lorsque cet état est reflété dans le message ExerciseUpdate
. ll est particulièrement important de prendre cela en compte pour les états d'interface utilisateur. Si l'utilisateur appuie sur "Pause", désactivez le bouton "Pause" et appelez pauseExerciseAsync()
sur Services Santé. Attendez que l'état de Services Santé soit mis en pause via ExerciseUpdate.exerciseStateInfo.state
, puis faites basculer le bouton pour qu'il permette à l'utilisateur de reprendre son entraînement. La mise à jour de l'état de Services Santé peut prendre un peu plus de temps que l'appui sur le bouton. Par conséquent, si vous associez toutes les modifications d'UI aux appuis sur le bouton, il se peut que l'UI ne soit pas synchronisée avec l'état de Services Santé.
Gardez cela à l'esprit dans les situations suivantes :
- La mise en pause automatique est activée : l'entraînement peut être mis en pause ou démarré sans interaction de l'utilisateur.
- Une autre application démarre un entraînement : votre entraînement peut être arrêté sans interaction de l'utilisateur.
Si l'entraînement de votre application est arrêté par une autre application, votre application doit gérer cette situation de façon optimale :
- Enregistrez l'état d'entraînement partiel pour que la progression de l'utilisateur ne soit pas effacée.
- Supprimez l'icône de l'activité en cours et envoyez une notification à l'utilisateur pour l'informer que son entraînement a été terminé par une autre application.
Gérez également le cas où les autorisations sont révoquées lors d'un exercice en cours. Cette information est transmise via l'état isEnded
, avec AUTO_END_PERMISSION_LOST
comme ExerciseEndReason
. Traitez ce cas de la même manière que l'arrêt par une autre application : enregistrez l'état partiel, supprimez l'icône d'activité en cours et informez l'utilisateur.
L'exemple suivant montre comment vérifier l'arrêt de manière appropriée :
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
if (update.exerciseStateInfo.state.isEnded) {
// Workout has either been ended by the user, or otherwise terminated
}
...
}
...
}
Gérer la durée active
Pendant un exercice, une application peut afficher la durée active de l'entraînement. L'application, Services Santé et le microcontrôleur de l'appareil
(MCU), l'architecture à faible consommation
responsable du suivi des entraînements. Tous doivent être synchronisés, avec
pour la même durée active. Pour faciliter cette gestion, Services Santé envoie un ActiveDurationCheckpoint
qui fournit un point d'ancrage à partir duquel l'application peut lancer son minuteur.
Étant donné que la durée active est envoyée par le MCU et peut mettre un peu de temps à arriver dans l'application, ActiveDurationCheckpoint
contient deux propriétés :
activeDuration
: durée d'activité de l'exercicetime
: date à laquelle la durée active ci-dessus a été calculée
Dans l'application, la durée active d'un exercice peut par conséquent être calculée à partir d'ActiveDurationCheckpoint
à l'aide de l'équation suivante :
(now() - checkpoint.time) + checkpoint.activeDuration
Cette équation tient compte du petit delta entre la durée active calculée sur le MCU et l'arrivée dans l'application. Elle permet d'alimenter un chronomètre dans l'application et de s'assurer que le minuteur de l'application est parfaitement aligné sur l'heure dans Services Santé et le MCU.
Si l'exercice est mis en pause, l'application doit attendre que le minuteur soit relancé dans l'interface utilisateur jusqu'à ce que le temps calculé dépasse celui qui est affiché dans l'interface utilisateur.
En effet, le signal de mise en pause peut atteindre Services Santé et le MCU avec un léger retard. Par exemple, si l'application est suspendue à t=10 secondes, Services Santé risque de ne pas fournir la mise à jour PAUSED
à l'application avant t=10,2 secondes.
Utiliser les données d'ExerciseClient
Les métriques correspondant aux types de données enregistrés par votre application sont transmises dans des messages ExerciseUpdate
.
Le processeur ne transmet les messages que lorsqu'il est activé ou lorsqu'une période de référence maximale est atteinte (par exemple, toutes les 150 secondes). Ne vous fiez pas à la fréquence de ExerciseUpdate
pour faire avancer un chronomètre avec l'activeDuration
. Consultez le
Exemple d'exercice
sur GitHub pour obtenir un exemple d'implémentation d'un chronomètre indépendant.
Lorsqu'un utilisateur commence un entraînement, des messages ExerciseUpdate
peuvent être distribués fréquemment, par exemple toutes les secondes. Lorsque l'utilisateur commence l'entraînement, l'écran peut s'éteindre. Services Santé peuvent ensuite diffuser des données moins souvent, mais toujours échantillonnées à la même fréquence, pour éviter d'activer le processeur principal. Lorsque l'utilisateur regarde l'écran, toutes les données en cours de traitement par lot sont immédiatement transmises à votre application.
Contrôler le débit de traitement par lot
Dans certains cas, vous pouvez contrôler la fréquence à laquelle votre application reçoit certains types de données lorsque l'écran est éteint. Un objet BatchingMode
permet à votre application d'ignorer le comportement de traitement par lot par défaut pour obtenir des envois de données plus fréquents.
Pour configurer le débit de traitement par lot, procédez comme suit :
Vérifiez si la définition
BatchingMode
particulière est prise en charge par l'appareil :// Confirm BatchingMode support to control heart rate stream to phone. suspend fun supportsHrWorkoutCompanionMode(): Boolean { val capabilities = exerciseClient.getCapabilities() return BatchingMode.HEART_RATE_5_SECONDS in capabilities.supportedBatchingModeOverrides }
Spécifiez que l'objet
ExerciseConfig
doit utiliser unBatchingMode
particulier, comme indiqué dans l'extrait de code suivant.val config = ExerciseConfig( exerciseType = ExerciseType.WORKOUT, dataTypes = setOf( DataType.HEART_RATE_BPM, DataType.TOTAL_CALORIES ), // ... batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS) )
Si vous le souhaitez, vous pouvez configurer
BatchingMode
de façon dynamique pendant l'entraînement, au lieu de conserver un comportement de traitement par lot spécifique pendant toute la durée de l'entraînement :val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS) exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
Pour effacer le
BatchingMode
personnalisé et revenir au comportement par défaut, transmettez un ensemble vide dansexerciseClient.overrideBatchingModesForActiveExercise()
.
Codes temporels
Le point dans le temps de chaque donnée correspond à la durée écoulée depuis le démarrage de l'appareil. Pour le convertir en horodatage, procédez comme suit :
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
Cette valeur peut ensuite être utilisée avec getStartInstant()
ou getEndInstant()
pour chaque point de données.
Précision des données
Certains types de données peuvent comporter des informations relatives à la précision associées à chaque point de données.
Ceci est représenté dans la propriété accuracy
.
Les classes HrAccuracy
et LocationAccuracy
peuvent être renseignées respectivement pour les types de données HEART_RATE_BPM
et LOCATION
. Le cas échéant, utilisez la propriété accuracy
pour déterminer si chaque point de données est suffisamment précis pour votre application.
Stocker et importer des données
Utilisez Room pour conserver les données fournies par Services Santé. L'importation des données a lieu à la fin de l'exercice, à l'aide d'un mécanisme comme Work Manager. Cela garantit que les appels réseau pour importer des données sont différés jusqu'à la fin de l'exercice, ce qui réduit la consommation d'énergie pendant l'exercice et simplifie le travail.
Liste de contrôle pour l'intégration
Avant de publier votre appli qui utilise l'appli Services Santé ExerciseClient
, consulter
la checklist suivante pour vous assurer que votre expérience utilisateur évite certains problèmes courants.
Vérifiez les points suivants :
- Votre application vérifie les fonctionnalités. du type d'exercice et des capacités de l'appareil chaque fois que l'application s'exécute. Vous pourrez ainsi détecter si un appareil ou un exercice en particulier n'est pas compatible. des types de données dont votre application a besoin.
- Vous demandez et gérez les autorisations nécessaires, et vous les spécifiez dans
votre fichier manifeste. Avant d'appeler
prepareExerciseAsync()
, votre application confirme que les autorisations d'exécution sont accordées. - Votre application utilise
getCurrentExerciseInfoAsync()
pour gérer les cas où: <ph type="x-smartling-placeholder">- </ph>
- Un exercice est déjà en cours de suivi et votre application remplace la précédente de l'exercice physique.
- Une autre application a mis fin à votre exercice. Cela peut se produire lorsque l'utilisateur rouvre l'application, il reçoit un message expliquant que l'exercice arrêté parce qu’une autre application a pris le relais.
- Si vous utilisez des données
LOCATION
: <ph type="x-smartling-placeholder">- </ph>
- Votre application gère un
ForegroundService
avec lesforegroundServiceType
pendant toute la durée de l'exercice (y compris l'appel de préparation). - Vérifiez que le GPS est activé sur l'appareil en utilisant
isProviderEnabled(LocationManager.GPS_PROVIDER)
, et invite l'utilisateur à ouvrez les paramètres de localisation si nécessaire. - Pour les cas d'utilisation exigeants, lorsque la réception de données de localisation la latence est très importante, envisagez d'intégrer la fonction Fused Fournisseur de localisation (FLP) et utiliser ses données comme correction de la localisation initiale. Lorsque plus stable les informations de localisation sont disponibles auprès des Services Santé, utilisez-les à la place de FLP.
- Votre application gère un
- Si votre application nécessite l'importation de données, tous les appels réseau pour importer des données reporté jusqu'à la fin de l'exercice. Sinon, tout au long de l'exercice, l'application effectue avec parcimonie les appels réseau nécessaires.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Mises à jour passives des données
- Services Santé sur Wear OS
- Premiers pas avec les cartes