Zapisywanie danych

Ten przewodnik opisuje proces zapisywania i aktualizowania danych w Health Connect.

Skonfiguruj strukturę danych

Zanim zapiszesz dane, musimy skonfigurować rekordy. W przypadku ponad 50 typów danych każdy z nich ma własną strukturę. Więcej informacji o dostępnych typach danych znajdziesz w dokumentacji Jetpacka.

Rekordy podstawowe

Typ danych Kroki w Health Connect rejestruje liczbę kroków wykonanych przez użytkownika między odczytami. Liczba kroków to typowy pomiar na platformach dotyczących zdrowia, fitnessu i samopoczucia.

Ten przykład pokazuje, jak ustawić dane liczby kroków:

val stepsRecord = StepsRecord(
    count = 120,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Zapisy z jednostkami miary

Health Connect może przechowywać wartości wraz z ich jednostkami miary, aby zapewnić dokładność. Przykładem może być rozległy i wyczerpujący typ danych Nutrition. Zawiera szeroką gamę opcjonalnych pól odżywczych, od zawartości węglowodanów łącznie po witaminy. Każdy punkt danych reprezentuje składniki odżywcze, które zostały potencjalnie spożyte w ramach posiłku lub produktu żywności.

W tym typie danych wszystkie składniki odżywcze są podawane w jednostkach Mass, a energy – w jednostce Energy.

Poniższy przykład pokazuje, jak ustawić dane żywieniowe dla użytkownika, który zjadł banana:

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 = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

Rekordy z danymi serii

Health Connect może przechowywać listę danych serii. Jednym z przykładów jest typ danych Tętno, który rejestruje serię próbek tętna wykrywanych między odczytami.

W tym typie danych parametr samples jest reprezentowany przez listę próbek tętna. Każda próbka zawiera wartości beatsPerMinute i time.

Poniższy przykład pokazuje, jak ustawić dane serii tętna:

val heartRateRecord = HeartRateRecord(
    startTime = START_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endTime = END_TIME,
    endZoneOffset = END_ZONE_OFFSET,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = START_TIME + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    }
)

Zapisywanie danych

Jednym z przepływów pracy w Health Connect jest zapisywanie danych. Aby dodać rekordy, użyj insertRecords.

Z przykładu poniżej dowiesz się, jak zapisywać liczbę kroków wstawiania danych:

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = START_TIME,
            endTime = END_TIME,
            startZoneOffset = START_ZONE_OFFSET,
            endZoneOffset = END_ZONE_OFFSET
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

Zaktualizuj dane

Jeśli musisz zmienić jeden lub więcej rekordów, zwłaszcza gdy musisz zsynchronizować magazyn danych aplikacji z danymi z Health Connect, możesz zaktualizować swoje dane. Istniejące dane można aktualizować na 2 sposoby zależne od identyfikatora użytego do znalezienia rekordów.

Metadane

Warto najpierw sprawdzić klasę Metadata, ponieważ jest to niezbędne podczas aktualizowania danych. Po utworzeniu każdy element Record w Health Connect ma pole metadata. Do synchronizacji można używać tych właściwości:

Właściwości Opis
id Każdy element Record w Health Connect ma unikalną wartość id.
Health Connect wypełnia to pole automatycznie podczas wstawiania nowego rekordu.
lastModifiedTime Każdy element Record zapisuje też czas ostatniej modyfikacji rekordu.
Health Connect wypełnia to pole automatycznie.
clientRecordId Każdy element Record może mieć powiązany unikalny identyfikator, który służy jako plik referencyjny w Twoim magazynie danych z aplikacjami.
Aplikacja podaje tę wartość.
clientRecordVersion Jeśli rekord zawiera clientRecordId, clientRecordVersion może umożliwiać synchronizację danych z wersją w Twoim magazynie danych aplikacji.
Aplikacja podaje tę wartość.

Zaktualizuj za pomocą identyfikatora rekordu

Aby zaktualizować dane, przygotuj najpierw niezbędne rekordy. W razie potrzeby wprowadź zmiany w rekordach. Następnie wywołaj updateRecords, aby wprowadzić zmiany.

Z przykładu poniżej dowiesz się, jak zaktualizować dane. W tym celu każdy rekord ma wartości przesunięcia strefy dostosowane do 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)
        }

        client.updateRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Wstaw przez upsert za pomocą identyfikatora rekordu klienta

Jeśli używasz opcjonalnych wartości identyfikatora rekordu klienta i wersji rekordu klienta, zalecamy użycie insertRecords zamiast updateRecords.

Funkcja insertRecords ma możliwość wstawiania danych przez upsert. Jeśli dane istnieją w Health Connect na podstawie podanego zestawu identyfikatorów rekordu klienta, zostaną zastąpione. W przeciwnym razie zostaną zapisane jako nowe dane. Ten scenariusz jest przydatny, gdy musisz synchronizować dane z magazynu danych aplikacji z Health Connect.

Poniższy przykład pokazuje, jak wykonać upsert na danych pobranych z magazynu danych aplikacji:

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(
        // Assign parameters for this record
        metadata = Metadata(
            clientRecordId = cid
        )
    )
    appStepsRecords.add(sr)
    // ...
    return appStepsRecords
}

suspend fun upsertSteps(
    healthConnectClient: HealthConnectClient,
    newStepsRecords: ArrayList<StepsRecord>
) {
    try {
        healthConnectClient.insertRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Potem możesz je wywoływać w wątku głównym.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Sprawdzanie wartości w wersji rekordu klienta

Jeśli proces upsertowania danych obejmuje wersję rekordu klienta, Health Connect przeprowadza testy porównawcze w wartościach clientRecordVersion. Jeśli wersja we wstawionych danych jest wyższa niż wersja z istniejących danych, następuje upsert. W przeciwnym razie zmiana zostanie zignorowana, a wartość pozostaje taka sama.

Aby uwzględnić obsługę wersji w danych, musisz podać Metadata.clientRecordVersion z wartością Long na podstawie logiki obsługi wersji.

val sr = StepsRecord(
    count = count,
    startTime = startTime,
    startZoneOffset = startZoneOffset,
    endTime = endTime,
    endZoneOffset = endZoneOffset,
    metadata = Metadata(
        clientRecordId = cid,
        clientRecordVersion = version
    )
)

Użycie przez upsert nie zwiększa automatycznie wartości version przy każdej zmianie, co zapobiega nieoczekiwanym zastąpieniu danych. W takim przypadku musisz ręcznie podać większą wartość.

Sprawdzone metody

Po zbudowaniu logiki pamiętaj o stosowaniu sprawdzonych metod podczas zapisywania i aktualizowania danych.