Ce guide est compatible avec la version 1.1.0-alpha12 de Santé Connect.
Ce guide explique comment écrire ou mettre à jour des données dans Santé Connect.
Configurer la structure des données
Avant d'écrire des données, nous devons configurer les enregistrements. Pour plus de 50 types de données, chacun présente sa propre structure. Consultez la documentation de référence de Jetpack pour en savoir plus sur les types de données disponibles.
Enregistrements de base
Le type de données Pas dans Santé Connect enregistre le nombre de pas qu'un utilisateur a effectués entre deux lectures. Le nombre de pas est une unité de mesure courante pour les plates-formes de santé, de remise en forme et de bien-être.
L'exemple suivant montre comment définir les données relatives au nombre de pas :
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))
val stepsRecord = StepsRecord(
count = 120,
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
)
)
Enregistrements avec unités de mesure
Pour plus de précision, Santé Connect peut stocker les valeurs avec leur unité de mesure. Par exemple, le type de données Nutrition est vaste et complet. Il comprend une grande variété de champs de nutriments facultatifs, tels que la quantité totale de glucides ou les vitamines. Chaque point de données représente les nutriments qui ont pu être consommés dans le cadre d'un repas ou d'un aliment.
Dans ce type de données, tous les nutriments sont représentés par des unités de masse (Mass
), alors que l'energy
est représentée en unité d'Energy
.
L'exemple suivant montre comment définir des données nutritionnelles pour un utilisateur qui a mangé une banane :
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(1))
val banana = NutritionRecord(
name = "banana",
energy = 105.0.kilocalories,
dietaryFiber = 3.1.grams,
potassium = 0.422.grams,
totalCarbohydrate = 27.0.grams,
totalFat = 0.4.grams,
saturatedFat = 0.1.grams,
sodium = 0.001.grams,
sugar = 14.0.grams,
vitaminB6 = 0.0005.grams,
vitaminC = 0.0103.grams,
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.manualEntry(
device = Device(type = Device.TYPE_PHONE)
)
)
Enregistrements avec données séquentielles
Santé Connect peut stocker une liste de données séquentielles. Le type de données Fréquence cardiaque en est un bon exemple. Il capture une série d'échantillons de pulsation détectés entre les lectures.
Dans ce type de données, le paramètre samples
est représenté par une liste d'échantillons de la fréquence cardiaque. Chaque exemple contient une valeur beatsPerMinute
et une valeur time
.
L'exemple suivant montre comment définir des données séquentielles pour la fréquence cardiaque :
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))
val heartRateRecord = HeartRateRecord(
startTime = startTime,
startZoneOffset = ZoneOffset.UTC,
endTime = endTime,
endZoneOffset = ZoneOffset.UTC,
// records 10 arbitrary data, to replace with actual data
samples = List(10) { index ->
HeartRateRecord.Sample(
time = startTime + Duration.ofSeconds(index.toLong()),
beatsPerMinute = 100 + index.toLong(),
)
},
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
))
Écrire des données
L'un des workflows courants de Santé Connect consiste à écrire des données. Pour ajouter des enregistrements, utilisez insertRecords
.
L'exemple suivant montre comment écrire des données pour insérer le nombre de pas :
suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))
try {
val stepsRecord = StepsRecord(
count = 120,
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.autoRecorded(
device = Device(type = Device.TYPE_WATCH)
)
)
healthConnectClient.insertRecords(listOf(stepsRecord))
} catch (e: Exception) {
// Run error handling here
}
}
Mettre à jour des données
Si vous devez modifier un ou plusieurs enregistrements, en particulier lorsque vous devez synchroniser le datastore de votre application avec les données de Santé Connect, vous pouvez les mettre à jour. Il existe deux façons de mettre à jour des données existantes en fonction de l'identifiant utilisé pour rechercher les enregistrements.
Métadonnées
Il est utile d'examiner d'abord la classe Metadata
, car cela est nécessaire pour mettre à jour les données. Lors de la création, chaque Record
dans Santé Connect comporte un champ metadata
. Les propriétés suivantes sont pertinentes pour la synchronisation :
Propriétés | Description |
---|---|
id
|
Chaque Record dans Santé Connect a une valeur id unique.Santé Connect la renseigne automatiquement lorsque vous insérez un nouvel enregistrement. |
lastModifiedTime
|
Chaque Record conserve la date de sa dernière modification.Santé Connect renseigne automatiquement cette information. |
clientRecordId
|
Chaque Record peut être associé à un identifiant unique qui servira de référence dans le datastore de votre application.
Votre application fournit cette valeur. |
clientRecordVersion
|
Lorsqu'un enregistrement est associé à un clientRecordId , vous pouvez utiliser clientRecordVersion pour permettre aux données de rester synchronisées avec la version du datastore de votre application.Votre application fournit cette valeur. |
Mettre à jour les données via un identifiant d'enregistrement
Pour mettre à jour les données, préparez d'abord les enregistrements nécessaires. Si nécessaire, modifiez les enregistrements. Appelez ensuite updateRecords
pour effectuer les modifications.
L'exemple suivant montre comment mettre à jour des données. À cette fin, les valeurs de décalage de zone de chaque enregistrement sont définies sur PST.
suspend fun updateSteps(
healthConnectClient: HealthConnectClient,
prevRecordStartTime: Instant,
prevRecordEndTime: Instant
) {
try {
val request = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(
prevRecordStartTime, prevRecordEndTime
)
)
)
val newStepsRecords = arrayListOf<StepsRecord>()
for (record in request.records) {
// Adjusted both offset values to reflect changes
val sr = StepsRecord(
count = record.count,
startTime = record.startTime,
startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
endTime = record.endTime,
endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
metadata = record.metadata
)
newStepsRecords.add(sr)
}
healthConnectClient.updateRecords(newStepsRecords)
} catch (e: Exception) {
// Run error handling here
}
}
Insérer les données mises à jour via l'identifiant de l'enregistrement client
Si vous utilisez les valeurs facultatives d'identifiant et de version de l'enregistrement client, nous vous recommandons d'utiliser insertRecords
au lieu de updateRecords
.
La fonction insertRecords
peut insérer les données mises à jour.
Si les données existent dans Santé Connect en fonction de l'ensemble donné d'identifiants d'enregistrements client, elles sont écrasées. Sinon, elles sont écrites en tant que nouvelles données.
Ce scénario est utile lorsque vous devez synchroniser les données du datastore de votre application avec Santé Connect.
L'exemple suivant montre comment effectuer une opération d'insertion des données mises à jour à partir du datastore de l'application :
suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
val appStepsRecords = arrayListOf<StepsRecord>()
// Pull data from app datastore
// ...
// Make changes to data if necessary
// ...
// Store data in appStepsRecords
// ...
var sr = StepsRecord(
metadata = Metadata.autoRecorded(
clientRecordId = "Your client record ID",
device = Device(type = Device.TYPE_WATCH)
),
// Assign more parameters for this record
)
appStepsRecords.add(sr)
// ...
return appStepsRecords
}
suspend fun upsertSteps(
healthConnectClient: HealthConnectClient,
newStepsRecords: ArrayList<StepsRecord>
) {
try {
healthConnectClient.insertRecords(newStepsRecords)
} catch (e: Exception) {
// Run error handling here
}
}
Vous pourrez ensuite appeler ces fonctions dans votre thread principal.
upsertSteps(healthConnectClient, pullStepsFromDatastore())
Vérification des valeurs dans la version de l'enregistrement client
Si votre processus d'insertion des données mises à jour inclut la version de l'enregistrement client, Santé Connect effectue des vérifications des valeurs clientRecordVersion
. Si la version des données insérées est ultérieure à celle des données existantes, l'insertion des données se produit. Sinon, le processus ignore la modification, et la valeur reste la même.
Pour inclure la gestion des versions dans vos données, vous devez fournir à Metadata.clientRecordVersion
une valeur Long
basée sur votre logique de gestion des versions.
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))
val stepsRecord = StepsRecord(
count = 100L,
startTime = startTime,
startZoneOffset = ZoneOffset.UTC,
endTime = endTime,
endZoneOffset = ZoneOffset.UTC,
metadata = Metadata.manualEntry(
clientRecordId = "Your supplied record ID",
clientRecordVersion = 0L, // Your supplied record version
device = Device(type = Device.TYPE_WATCH)
)
)
Les insertions n'incrémentent pas automatiquement la version
à chaque modification, ce qui évite tout écrasement inattendu des données. Vous devez donc lui attribuer manuellement une valeur plus élevée.
Bonnes pratiques pour écrire des données
Les applications ne doivent écrire dans Santé Connect que des données dont elles sont la source.
Si les données ont été importées depuis une autre application, la responsabilité d'écriture dans Santé Connect incombe à cette application.
Il est également conseillé d'implémenter une logique qui gère les exceptions d'écriture (par exemple, les données qui se trouvent en dehors des limites ou les erreurs système internes). Vous pouvez appliquer vos stratégies d'intervalle entre les tentatives et de nouvelles tentatives au niveau d'un mécanisme de planification des tâches. Si l'écriture sur Santé Connect échoue, assurez-vous que votre application peut passer outre ce point d'exportation. N'oubliez pas de consigner et de signaler les erreurs pour faciliter le diagnostic.
Lorsque vous suivez les données, quelques suggestions peuvent vous aider en fonction de la manière dont votre application écrit les données.
Suivi passif
Cela inclut les applications qui effectuent un suivi passif de la condition physique ou de la santé, comme l'enregistrement continu d'un nombre de pas ou d'une fréquence cardiaque.
Votre application doit écrire régulièrement des données dans Santé Connect comme suit :
- Lors de chaque synchronisation, n'écrivez que les nouvelles données et ne mettez à jour que les données modifiées depuis la dernière synchronisation.
- Limitez les requêtes à 1 000 enregistrements par requête d'écriture.
- Utilisez
WorkManager
pour planifier les tâches périodiques en arrière-plan, d'une durée minimale de 15 minutes. Permettez l'exécution des tâches uniquement lorsque l'appareil est inactif et qu'il n'est pas à court de batterie.
val constraints = Constraints.Builder() .requiresBatteryNotLow() .requiresDeviceIdle(true) .build() val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>( 15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES ) .setConstraints(constraints) .build()
Suivi actif
Cela inclut les applications qui effectuent le suivi des événements comme les entraînements et le sommeil, ou les entrées manuelles des utilisateurs, comme la nutrition. Ces enregistrements sont créés lorsque l'application est exécutée au premier plan ou sont des événements occasionnels qui se produisent tout au plus quelques fois par jour.
Assurez-vous que votre application n'entraîne pas l'exécution continue de Santé Connect pendant toute la durée de l'événement.
Les données doivent être écrites dans Santé Connect de l'une des deux manières suivantes :
- Synchronisez les données avec Santé Connect une fois l'événement terminé (par exemple, lorsque l'utilisateur met fin à un entraînement dont le suivi était effectué).
- Planifiez une tâche ponctuelle à l'aide de
WorkManager
pour synchroniser les données ultérieurement.
Bonnes pratiques concernant la granularité et la fréquence des écritures
Lorsque vous écrivez des données dans Santé Connect, utilisez une résolution appropriée. L'utilisation de la résolution appropriée permet de réduire la charge de stockage, tout en conservant des données cohérentes et précises. La résolution des données comprend deux éléments:
- Fréquence des écritures: fréquence à laquelle votre application envoie de nouvelles données dans Santé Connect. Par exemple, écrivez de nouvelles données toutes les 15 minutes.
- Précision des données écrites: fréquence d'échantillonnage des données transmises. Par exemple, écrivez des échantillons de fréquence cardiaque toutes les cinq secondes. Tous les types de données ne nécessitent pas le même taux d'échantillonnage. Une mise à jour des données liées au nombre de pas à chaque seconde présente peu d'avantages, par rapport à une cadence moins fréquente (toutes les 60 secondes, par exemple). Toutefois, des taux d'échantillonnage plus faibles peuvent donner aux utilisateurs un aperçu plus détaillé et précis de leurs données de santé et de remise en forme. Les fréquences d'échantillonnage doivent trouver un juste milieu entre le niveau de détail et les performances.
Écrire des données surveillées tout au long de la journée
Pour les données collectées en continu, comme les pas, votre application doit écrire dans Santé Connect au moins toutes les 15 minutes tout au long de la journée.
Type de données |
Unité |
Attendu |
Exemple |
Étapes |
pas |
Toutes les minutes |
23:14 - 23:15 - 5 steps 23:16 - 23:17 - 22 steps 23:17 - 23:18 - 8 steps |
StepsCadence |
pas/min |
Toutes les minutes |
23:14 - 23:15 - 5 ppm 23:16 - 23:17 - 22 spm 23:17 - 23:18 - 8 spm |
Poussées de fauteuil roulant |
poussées |
Toutes les minutes |
23:14 - 23:15 - 5 pushs 23:16 - 23:17 - 22 pushs 23:17 - 23:18 - 8 pushes |
ActiveCaloriesBurned |
Calories |
Toutes les 15 minutes |
23:15 - 23:30 - 2 Calories 23h30 à 23h45 : 25 calories 23:45 - 00:00 - 5 Calories |
TotalCaloriesBurned |
Calories |
Toutes les 15 minutes |
23:15-23:30 : 16 calories 23:30 à 23:45 : 16 calories 23:45 - 00:00 - 16 calories |
Distance |
km/min |
Toutes les minutes |
23:14-23:15 : 0,008 km 23:16 - 23:16 - 0,021 km 23:17 - 23:18 - 0,012 km |
ElevationGained |
m |
Toutes les minutes |
20:36 - 20:37 - 3,048 m 20:39 - 20:40 - 3,048 m 23:23 - 23:24 - 9.144m |
FloorsClimbed |
étages |
Toutes les minutes |
23:14 - 23:15 - 5 floors 23:16 - 23:16 - 22 étages 23:17 - 23:18 - 8 étages |
HeartRate |
bpm |
Toutes les minutes |
6:11 - 55 bpm |
HeartRateVariabilityRmssd |
ms |
Toutes les minutes |
6:11 - 23 ms |
RespiratoryRate |
respirations/minute |
Toutes les minutes |
23:14 - 23:15 : 60 respirations par minute 23:16 - 23:16 - 62 respirations/minute 23:17 - 23:18 : 64 respirations/minute |
OxygenSaturation |
% |
Toutes les heures |
6:11 - 95,208% |
Écrire des sessions
Les données doivent être écrites dans Santé Connect à la fin de l'entraînement ou de la session de sommeil.
Il est recommandé d'écrire toute session de sommeil ou d'exercice avec l'appareil d'enregistrement et les métadonnées appropriées, y compris RecordingMethod
.
Au minimum, votre application doit suivre les conseils de la colonne "Attendu" ci-dessous. Dans la mesure du possible, suivez les conseils "meilleurs".
Données collectées pendant un exercice
Type de données |
Unité |
Attendu |
Cordialement, |
Exemple |
Étapes |
pas |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 5 étapes 23:16 - 23:17 - 22 steps 23:17 - 23:18 - 8 steps |
StepsCadence |
pas/min |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 35 ppm 23:16 - 23:17 - 37 spm 23:17 - 23:18 - 40 spm |
Poussées de fauteuil roulant |
poussées |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 5 pushs 23:16 - 23:17 - 22 pushs 23:17 - 23:18 - 8 pushes |
CyclingPedalingCadence |
rpm |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 65 rpm 23:16 - 23:17 - 70 tr/min 23:17 - 23:18 - 68 tr/min |
Énergie |
watts |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 250 watts 23:16 - 23:17 - 255 watts 23:17 - 23:18 - 245 watts |
Vitesse |
km/min |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 0,3 km/min 23:16 - 23:17 - 0.4 km/min 23:17 - 23:18 -0.4 km/min |
Distance |
km/m |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 0,008 km 23:16 - 23:16 - 0,021 km 23:17 - 23:18 - 0,012 km |
ActiveCaloriesBurned |
Calories |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 20 calories 23:16 - 23:17 - 20 calories 23:17 - 23:18 - 25 calories |
TotalCaloriesBurned |
Calories |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 : 36 calories 23:16 - 23:17 - 36 calories 23:17 - 23:18 - 41 calories |
ElevationGained |
m |
Toutes les minutes |
Toutes les secondes |
20:36 - 20:37 - 3,048 m 20:39 - 20:40 - 3,048 m 23:23 - 23:24 - 9.144m |
ExerciseRoutes |
lat/lng/alt |
Toutes les 3 à 5 secondes |
Toutes les secondes |
|
HeartRate |
bpm |
Toutes les minutes |
Toutes les secondes |
23:14-23:15 - 150 bpm 23:16 - 23:17 -152 bpm 23:17 - 23:18 - 155 bpm |
Données suivies pendant le sommeil
Type de données |
Unité |
Échantillons attendus |
Exemple |
Analyse des différentes phases du sommeil |
étape |
Période précise par phase de sommeil |
23:46 - 23:50 - awake 23:50 - 23:56 : sommeil léger 23:56 - 00:16 - deep sleep |
RestingHeartRate |
bpm |
Valeur quotidienne unique (à fournir dès le matin) |
6:11 - 60 bpm |
OxygenSaturation |
% |
Valeur quotidienne unique (à fournir dès le matin) |
6:11 - 95,208% |