Écrire des données

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:

  1. 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.
  2. 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%