Daten schreiben

Dieser Leitfaden ist mit der Health Connect-Version 1.1.0-alpha12 kompatibel.

In diesem Leitfaden erfahren Sie, wie Sie Daten in Health Connect schreiben oder aktualisieren.

Datenstruktur einrichten

Bevor wir Daten schreiben, müssen wir die Einträge einrichten. Für mehr als 50 Datentypen gibt es jeweils eigene Strukturen. Weitere Informationen zu den verfügbaren Datentypen finden Sie in der Jetpack-Referenz.

Einfache Einträge

Der Datentyp Schritte in Health Connect erfasst die Anzahl der Schritte, die ein Nutzer zwischen den Messungen zurückgelegt hat. Die Schrittzahl ist eine gängige Messgröße auf Gesundheits-, Fitness- und Wellnessplattformen.

Im folgenden Beispiel wird gezeigt, wie Sie Daten zur Schrittzahl festlegen:

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)
    )
)

Einträge mit Maßeinheiten

In Health Connect können Werte zusammen mit ihren Maßeinheiten gespeichert werden, um für Genauigkeit zu sorgen. Ein Beispiel ist der Datentyp Nutrition, der umfangreich und umfassend ist. Sie enthält eine Vielzahl optionaler Nährstofffelder, von Kohlenhydraten insgesamt bis hin zu Vitaminen. Jeder Datenpunkt steht für die Nährstoffe, die möglicherweise im Rahmen einer Mahlzeit oder eines Lebensmittels aufgenommen wurden.

Bei diesem Datentyp werden alle Nährstoffe in Einheiten von Mass dargestellt, während energy in einer Einheit von Energy dargestellt wird.

Im folgenden Beispiel wird gezeigt, wie du Nährwertdaten für einen Nutzer festlegst, der eine Banane gegessen hat:

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)
    )
)

Einträge mit Reihendaten

In Health Connect kann eine Liste von Reihendaten gespeichert werden. Ein Beispiel ist der Datentyp Herzfrequenz, mit dem eine Reihe von Herzschlag-Stichproben erfasst wird, die zwischen den Messungen erkannt werden.

Bei diesem Datentyp wird der Parameter samples durch eine Liste von Herzfrequenz-Samples dargestellt. Jedes Sample enthält einen beatsPerMinute-Wert und einen time-Wert.

Im folgenden Beispiel wird gezeigt, wie Sie Daten für die Herzfrequenzreihe festlegen:

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)
    ))

Daten schreiben

Einer der gängigen Workflows in Health Connect ist das Schreiben von Daten. Verwenden Sie insertRecords, um Einträge hinzuzufügen.

Im folgenden Beispiel wird gezeigt, wie Schrittzahlen für das Einfügen von Daten geschrieben werden:

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
    }
}

Daten aktualisieren

Wenn Sie einen oder mehrere Einträge ändern müssen, insbesondere wenn Sie Ihren App-Datenspeicher mit Daten aus Health Connect synchronisieren müssen, können Sie Ihre Daten aktualisieren. Es gibt zwei Möglichkeiten, vorhandene Daten zu aktualisieren. Welche davon verwendet wird, hängt von der Kennung ab, die zum Finden von Einträgen verwendet wird.

Metadaten

Es empfiehlt sich, zuerst die Metadata-Klasse zu untersuchen, da dies beim Aktualisieren von Daten erforderlich ist. Bei der Erstellung hat jeder Record in Health Connect das Feld metadata. Die folgenden Properties sind für die Synchronisierung relevant:

Properties Beschreibung
id Jede Record in Health Connect hat einen eindeutigen id-Wert.
Dieser Wert wird von Health Connect automatisch eingefügt, wenn ein neuer Datensatz eingefügt wird.
lastModifiedTime In jedem Record wird auch aufgezeichnet, wann der Datensatz zuletzt geändert wurde.
Dieser Wert wird automatisch von Health Connect ausgefüllt.
clientRecordId Jedem Record kann eine eindeutige ID zugewiesen werden, die als Referenz in Ihrem App-Datenspeicher dient.
Diesen Wert liefert Ihre App.
clientRecordVersion Wenn ein Eintrag clientRecordId hat, kann clientRecordVersion verwendet werden, um die Daten mit der Version in Ihrem App-Datenspeicher zu synchronisieren.
Diesen Wert liefert Ihre App.

Über die Datensatz-ID aktualisieren

Wenn Sie Daten aktualisieren möchten, müssen Sie zuerst die erforderlichen Einträge vorbereiten. Nehmen Sie bei Bedarf Änderungen an den Einträgen vor. Rufen Sie dann updateRecords auf, um die Änderungen vorzunehmen.

Im folgenden Beispiel wird gezeigt, wie Daten aktualisiert werden. Dazu werden die Zeitzonenverschiebungen der einzelnen Einträge auf PST umgestellt.

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
    }
}

Upsert über die Client-Eintrags-ID

Wenn Sie die optionalen Werte „Client Record ID“ und „Client Record Version“ verwenden, empfehlen wir, stattdessen insertRecords anstelle von updateRecords zu verwenden.

Mit der Funktion insertRecords können Daten upsert werden. Wenn die Daten in Health Connect basierend auf den angegebenen Client-Eintrags-IDs vorhanden sind, werden sie überschrieben. Andernfalls werden sie als neue Daten geschrieben. Dieses Szenario ist nützlich, wenn Sie Daten aus Ihrem App-Datenspeicher mit Health Connect synchronisieren müssen.

Im folgenden Beispiel wird gezeigt, wie ein Upsert für Daten ausgeführt wird, die aus dem App-Datastore abgerufen wurden:

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
    }
}

Anschließend können Sie diese Funktionen in Ihrem Hauptthread aufrufen.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Wertprüfung in der Version des Kundeneintrags

Wenn Ihr Upsert-Prozess die Version des Kundeneintrags enthält, führt Health Connect Vergleichsüberprüfungen an den clientRecordVersion-Werten durch. Wenn die Version der eingefügten Daten höher als die Version der vorhandenen Daten ist, wird der Upsert ausgeführt. Andernfalls wird die Änderung vom Prozess ignoriert und der Wert bleibt unverändert.

Wenn Sie Versionen in Ihre Daten aufnehmen möchten, müssen Sie Metadata.clientRecordVersion einen Long-Wert basierend auf Ihrer Versionslogik angeben.

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)
    )
)

Bei Upserts wird version nicht automatisch erhöht, wenn es Änderungen gibt. So wird verhindert, dass Daten unerwartet überschrieben werden. In diesem Fall müssen Sie manuell einen höheren Wert angeben.

Best Practices für das Schreiben von Daten

Apps dürfen nur eigene Daten in Health Connect schreiben.

Wenn Daten in Ihrer App aus einer anderen App importiert wurden, liegt die Verantwortung für das Schreiben der eigenen Daten in Health Connect bei der anderen App.

Es empfiehlt sich auch, Logik zu implementieren, die Schreibausnahmen behandelt, z. B. wenn Daten außerhalb des zulässigen Bereichs liegen oder ein interner Systemfehler auftritt. Sie können Ihre Backoff- und Wiederholungsstrategien auf einen Jobplanungsmechanismus anwenden. Wenn das Schreiben in Health Connect letztendlich fehlschlägt, achten Sie darauf, dass Ihre App diesen Exportpunkt überspringen kann. Vergessen Sie nicht, Fehler zu protokollieren und zu melden, um die Diagnose zu erleichtern.

Beim Erfassen von Daten können Sie je nach Art der Datenspeicherung in Ihrer App einige Vorschläge befolgen.

Passives Tracking

Dazu gehören auch Apps, die ein passives Fitness- oder Gesundheits-Tracking durchführen, z. B. durch kontinuierliche Aufzeichnung von Schritten oder der Herzfrequenz im Hintergrund.

Ihre App muss regelmäßig Daten in Health Connect schreiben. Das ist auf folgende Arten möglich:

  • Bei jeder Synchronisierung werden nur neue Daten und aktualisierte Daten geschrieben, die seit der letzten Synchronisierung geändert wurden.
  • Anfragen in Chunks mit maximal 1.000 Einträgen pro Schreibanfrage senden.
  • Verwenden Sie WorkManager, um regelmäßige Hintergrundaufgaben mit einem Zeitraum von mindestens 15 Minuten zu planen.
  • Aufgaben können so eingeschränkt werden, dass sie nur ausgeführt werden, wenn das Gerät inaktiv ist und der Akkustand nicht niedrig ist.

    val constraints = Constraints.Builder()
        .requiresBatteryNotLow()
        .requiresDeviceIdle(true)
        .build()
    
    val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
            15,
            TimeUnit.MINUTES,
            5,
            TimeUnit.MINUTES
        )
        .setConstraints(constraints)
        .build()
    

Aktives Tracking

Dazu gehören Apps, die ereignisbasiertes Tracking wie Bewegung und Schlaf oder manuelle Nutzereingaben wie Ernährung durchführen. Diese Einträge werden erstellt, wenn die App im Vordergrund ist, oder in seltenen Fällen, in denen sie mehrmals am Tag verwendet wird.

Achten Sie darauf, dass Health Connect in Ihrer App nicht während der gesamten Dauer des Ereignisses ausgeführt wird.

Daten müssen auf eine der folgenden Arten in Health Connect geschrieben werden:

  • Synchronisiere die Daten nach dem Ende des Ereignisses mit Health Connect. Beispiel: Daten werden synchronisiert, wenn der Nutzer eine aufgezeichnete Trainingseinheit beendet.
  • Planen Sie mit WorkManager eine einmalige Aufgabe, um die Daten später zu synchronisieren.

Best Practices für Detaillierung und Häufigkeit von Schreibvorgängen

Verwenden Sie beim Schreiben von Daten in Health Connect die richtige Auflösung. Die Verwendung der richtigen Auflösung trägt dazu bei, die Speicherauslastung zu reduzieren und gleichzeitig konsistente und korrekte Daten zu erhalten. Die Datenauflösung umfasst zwei Dinge:

  1. Häufigkeit von Schreibvorgängen: Gibt an, wie oft Ihre Anwendung neue Daten in Health Connect sendet. Beispiel: Schreiben Sie neue Daten alle 15 Minuten.
  2. Granularität der geschriebenen Daten: gibt an, wie oft die gesendeten Daten gesampled wurden. Beispiel: Herzfrequenzdaten alle 5 Sekunden schreiben Nicht für jeden Datentyp ist dieselbe Abtastrate erforderlich. Es bringt nur wenig, die Schrittzahldaten jede Sekunde zu aktualisieren, anstatt sie weniger häufig, z. B. alle 60 Sekunden, zu aktualisieren. Höhere Abtastrate kann Nutzern jedoch einen detaillierteren und detaillierteren Überblick über ihre Gesundheits- und Fitnessdaten bieten. Die Abtastrate sollte ein ausgewogenes Verhältnis zwischen Detailtreue und Leistung bieten.

Daten schreiben, die den ganzen Tag über erfasst werden

Bei fortlaufend erfassten Daten wie Schritten sollte Ihre App mindestens alle 15 Minuten Daten an Health Connect senden.

Datentyp

Einheit

Erwartet

Beispiel

Schritte

Schritte

Jede Minute

23:14 – 23:15 – 5 Schritte

23:16 – 23:17 – 22 Schritte

23:17 – 23:18 – 8 Schritte

Schrittfrequenz

Schritte/min

Jede Minute

23:14–23:15 – 5 SPM

23:16–23:17 – 22 SPM

23:17–23:18 – 8 Spm

Rollstuhlanschübe

pushes

Jede Minute

23:14 bis 23:15 – 5 Pushes

23:16–23:17 – 22 Pushes

23:17–23:18 – 8 Pushes

ActiveCaloriesBurned

Kalorien

Alle 15 Minuten

23:15–23:30 Uhr – 2 Kalorien

23:30–23:45 Uhr – 25 Kalorien

23:45–00:00 Uhr – 5 Kalorien

TotalCaloriesBurned

Kalorien

Alle 15 Minuten

23:15–23:30 Uhr – 16 Kalorien

23:30–23:45 Uhr – 16 Kalorien

23:45–00:00 Uhr – 16 Kalorien

Strecke

km/min

Jede Minute

23:14–23:15 – 0,008 km

23:16 – 23:16 – 0,021 km

23:17–23:18 – 0,012 km

ElevationGained

m

Jede Minute

20:36 – 20:37 – 3,048 m

20:39 – 20:40 – 3,048 m

23:23 – 23:24 – 9,144 m

FloorsClimbed

Stockwerke

Jede Minute

23:14–23:15 – 5 Stockwerke

23:16 – 23:16 – 22 Stockwerke

23:17–23:18 – 8 Stockwerke

Herzfrequenz

bpm

Jede Minute

6:11 Uhr – 55 bpm

HeartRateVariabilityRmssd

ms

Jede Minute

6:11 Uhr – 23 ms

Atemfrequenz

Atemzüge pro Minute

Jede Minute

23:14 – 23:15 – 60 Atemzüge pro Minute

23:16 – 23:16 – 62 Atemzüge pro Minute

23:17 – 23:18 – 64 Atemzüge pro Minute

Sauerstoffsättigung

%

Stündlich

6:11 – 95,208%

Sitzungen schreiben

Die Daten sollten am Ende des Trainings oder der Schlafsitzung in Health Connect geschrieben werden.

Als Best Practice sollten alle Schlaf- oder Trainingssitzungen mit dem Aufnahmegerät und den entsprechenden Metadaten, einschließlich RecordingMethod, aufgezeichnet werden.

Ihre Anwendung sollte mindestens den Vorgaben in der Spalte „Erwartet“ unten entsprechen. Folgen Sie nach Möglichkeit der Anleitung mit dem Zusatz „am besten“.

Während eines Trainings erfasste Daten

Datentyp

Einheit

Erwartet

Viele Grüße

Beispiel

Schritte

Schritte

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 5 Schritte

23:16 – 23:17 – 22 Schritte

23:17 – 23:18 – 8 Schritte

Schrittfrequenz

Schritte/min

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 35 SPM

23:16–23:17 – 37 SPM

23:17 – 23:18 – 40 Spm

Rollstuhlanschübe

pushes

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 5 Pushes

23:16–23:17 – 22 Pushes

23:17–23:18 – 8 Pushes

CyclingPedalingCadence

AZ/min

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 65 U/min

23:16–23:17 – 70 U/min

23:17 – 23:18 – 68 U/min

Leistung

Watt

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 250 Watt

23:16 – 23:17 – 255 Watt

23:17 – 23:18 – 245 Watt

Geschwindigkeit

km/min

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 0,3 km/Min.

23:16–23:17 – 0,4 km/Min.

23:17–23:18 – −0,4 km/Min.

Strecke

km/m

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 0,008 km

23:16 – 23:16 – 0,021 km

23:17–23:18 – 0,012 km

ActiveCaloriesBurned

Kalorien

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 20 Kalorien

23:16–23:17 – 20 Kalorien

23:17 – 23:18 – 25 Kalorien

TotalCaloriesBurned

Kalorien

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 36 Kalorien

23:16–23:17 – 36 Kalorien

23:17–23:18 – 41 Kalorien

ElevationGained

m

Jede Minute

Alle 1 Sekunde

20:36 – 20:37 – 3,048 m

20:39 – 20:40 – 3,048 m

23:23 – 23:24 – 9,144 m

ExerciseRoutes

lat/lng/alt

Alle 3–5 Sekunden

Alle 1 Sekunde

Herzfrequenz

bpm

Jede Minute

Alle 1 Sekunde

23:14–23:15 – 150 bpm

23:16–23:17 – 152 bpm

23:17–23:18 – 155 bpm

Während des Schlafs erfasste Daten

Datentyp

Einheit

Erwartete Stichproben

Beispiel

Schlafphasen

Phase

Detaillierte Zeiträume pro Schlafphase

23:46–23:50 Uhr – wach

23:50–23:56 – Leichtschlaf

23:56–00:16 Uhr – Tiefschlaf

Ruhepuls

bpm

Einzeln täglicher Wert (erwartet wird eine Meldung am Morgen)

6:11 Uhr – 60 bpm

Sauerstoffsättigung

%

Einzeln täglicher Wert (erwartet wird eine Meldung am Morgen)

6:11 – 95,208%