Zapisywanie danych

Ten przewodnik jest zgodny z wersją Health Connect 1.1.0-alpha12.

W tym przewodniku omówiliśmy proces zapisywania i aktualizowania danych w Health Connect.

Konfigurowanie struktury danych

Zanim zapiszemy dane, musimy najpierw skonfigurować rekordy. Istnieje ponad 50 typów danych, z których każdy ma swoją strukturę. Więcej informacji o dostępnych typach danych znajdziesz w dokumentacji Jetpacka.

Podstawowe rekordy

Typ danych Kroki w Health Connect rejestruje liczbę kroków wykonanych przez użytkownika między odczytami. Licznik kroków to powszechny pomiar na platformach związanych ze zdrowiem, kondycją i wellness.

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

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

Rekordy z jednostkami miary

Health Connect może przechowywać wartości wraz z jednostkami miary, aby zapewnić dokładność. Przykładem jest typ danych Nutrition, który jest obszerny i wszechstronny. Obejmuje ona wiele opcjonalnych pól składników odżywczych, od węglowodanów po witaminy. Każdy punkt danych przedstawia składniki odżywcze, które mogły zostać spożyte w ramach posiłku lub produktu spożywczego.

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

Ten przykład pokazuje, jak ustawić dane dotyczące wartości odżywczej dla użytkownika, który zjadł banana:

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

Rekordy z danymi serii

Health Connect może przechowywać listę danych serii. Przykładem jest typ danych Tętno, który rejestruje serię próbek bicia serca wykrytych między odczytami.

W przypadku tego typu danych parametr samples jest reprezentowany przez listę próbek tętna. Każda próbka zawiera wartość beatsPerMinute i wartość time.

Ten przykład pokazuje, jak ustawić dane serii tętna:

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

Zapisywanie danych

Jednym z częstych procesów w Health Connect jest zapisywanie danych. Aby dodać rekordy, użyj insertRecords.

Ten przykład pokazuje, jak zapisać liczbę kroków wstawiania danych:

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

Aktualizowanie danych

Jeśli chcesz zmienić co najmniej 1 rekord, zwłaszcza gdy musisz zsynchronizować bazę danych aplikacji z danymi z Health Connect, możesz zaktualizować swoje dane. Istnieją 2 sposoby aktualizowania dotychczasowych danych. Zależy to od identyfikatora używanego do znajdowania rekordów.

Metadane

Warto najpierw zbadać klasę Metadata, ponieważ jest to konieczne podczas aktualizowania danych. W momencie utworzenia każdy typ danych Record w Health Connect ma pole metadata. W przypadku synchronizacji istotne są te właściwości:

Właściwości Opis
id Każdy Record w Health Connect ma unikalną wartość id.
Health Connect automatycznie wypełnia to pole podczas wstawiania nowego rekordu.
lastModifiedTime Każdy element Record przechowuje też informację o ostatniej modyfikacji rekordu.
Health Connect wypełnia to automatycznie.
clientRecordId Każdy element Record może mieć powiązany unikalny identyfikator, który służy jako odniesienie w danych aplikacji.
Tę wartość podaje aplikacja.
clientRecordVersion Jeśli rekord ma wartość clientRecordId, możesz użyć wartości clientRecordVersion, aby dane były zsynchronizowane z wersją w puli danych aplikacji.
Tę wartość podaje aplikacja.

Aktualizacja za pomocą identyfikatora rekordu

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

Ten przykład pokazuje, jak zaktualizować dane. W tym celu każda pozycja ma wartości przesunięcia strefy czasowej skorygowane na czas 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
    }
}

Wgrywanie i aktualizowanie za pomocą identyfikatora rekordu klienta

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

Funkcja insertRecords umożliwia upsertowanie danych. Jeśli dane istnieją w Health Connect na podstawie podanego zbioru identyfikatorów rekordów klienta, zostaną zastąpione. W przeciwnym razie są one zapisywane jako nowe dane. Ten scenariusz jest przydatny, gdy chcesz zsynchronizować dane z danych aplikacji z Health Connect.

Ten przykład pokazuje, jak wykonać operację upsert na danych pobranych z 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(
        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
    }
}

Następnie możesz wywoływać te funkcje w głównym wątku.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Sprawdzanie wartości w wersji rekordu klienta

Jeśli proces aktualizacji danych obejmuje wersję rekordu klienta, Health Connect przeprowadza porównania w wartościach clientRecordVersion. Jeśli wersja z wstawionych danych jest wyższa niż wersja z dotychczasowych danych, następuje aktualizacja. W przeciwnym razie proces zignoruje zmianę, a wartość pozostanie taka sama.

Aby uwzględnić wersjonowanie w danych, musisz podać wartość Metadata.clientRecordVersion z wartością Long określoną na podstawie logiki wersji.

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

Operacje upsert nie zwiększają automatycznie wartości version, gdy występują zmiany, zapobiegając nieoczekiwanym przypadkom nadpisywania danych. W tym przypadku musisz ręcznie podać wyższą wartość.

Sprawdzone metody zapisywania danych

Aplikacje mogą zapisywać w Health Connect tylko dane pochodzące z własnych źródeł.

Jeśli dane w Twojej aplikacji zostały zaimportowane z innej aplikacji, to ta druga aplikacja jest odpowiedzialna za zapisywanie własnych danych w Health Connect.

Warto też zaimplementować logikę, która obsługuje wyjątki podczas zapisywania, takie jak dane poza zakresem lub błąd wewnętrzny systemu. Możesz zastosować swoje strategie wycofywania i ponownego próbowania w mechanizmie planowania zadań. Jeśli zapisywanie danych w Health Connect nie powiedzie się, sprawdź, czy aplikacja może przejść przez ten punkt eksportu. Aby ułatwić diagnozę, nie zapomnij odnotować i zgłosić błędów.

Podczas śledzenia danych możesz postępować zgodnie z kilkoma sugestiami, w zależności od sposobu zapisywania danych przez aplikację.

Śledzenie pasywne

Dotyczy to również aplikacji, które wykonują pasywne śledzenie aktywności fizycznej lub stanu zdrowia, np. ciągłe rejestrowanie kroków lub tętna w tle.

Aplikacja musi okresowo zapisywać dane w Health Connect w następujący sposób:

  • Podczas każdej synchronizacji zapisuj tylko nowe dane i zaktualizowane dane, które zostały zmodyfikowane od czasu ostatniej synchronizacji.
  • Podziel żądania na fragmenty, aby na każde żądanie zapisu przypadało maksymalnie 1000 rekordów.
  • Użyj polecenia WorkManager, aby zaplanować okresowe zadania w tle z okresem co najmniej 15 minut.
  • Ogranicz zadania do działania tylko wtedy, gdy urządzenie jest nieaktywne i nie ma niskiego poziomu naładowania baterii.

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

Aktywna lokalizacja

Dotyczy to aplikacji, które śledzą dane na podstawie zdarzeń, takich jak ćwiczenia i sen, lub danych wprowadzanych ręcznie przez użytkownika, np. dotyczących odżywiania. Te rekordy są tworzone, gdy aplikacja jest na pierwszym planie, lub w rzadkich przypadkach, gdy jest używana kilka razy dziennie.

Upewnij się, że aplikacja nie utrzymuje Health Connect w stanie działania przez cały czas trwania zdarzenia.

Dane muszą być zapisywane w Health Connect w jeden z 2 sposobów:

  • Po zakończeniu wydarzenia zsynchronizuj dane z Health Connect. Na przykład zsynchronizuj dane, gdy użytkownik zakończy śledzenie sesji ćwiczeń.
  • Zaplanuj jednorazowe zadanie za pomocą WorkManager, aby zsynchronizować dane w późniejszym terminie.

Sprawdzone metody dotyczące szczegółowości i częstotliwości zapisów

Podczas zapisywania danych w Health Connect używaj odpowiedniej rozdzielczości. Korzystanie z odpowiedniej rozdzielczości pomaga zmniejszyć obciążenie pamięci, a jednocześnie zachować spójne i prawidłowe dane. Rozdzielczość danych obejmuje 2 elementy:

  1. Częstotliwość zapisywania: określa, jak często aplikacja przesyła nowe dane do Health Connect. Na przykład zapisywać nowe dane co 15 minut.
  2. Szczegółowość zapisywanych danych: jak często dane, które są przesyłane, były próbkowane. Na przykład zapisuj próbki tętna co 5 s. Nie wszystkie typy danych wymagają tej samej częstotliwości próbkowania. Aktualizowanie danych o liczbie kroków co sekundę nie przynosi wielu korzyści w porównaniu z rzadszym odświeżaniem, np. co 60 sekund. Jednak wyższe częstotliwości próbkowania mogą zapewnić użytkownikom bardziej szczegółowy wgląd w ich dane dotyczące zdrowia i kondycji. Częstotliwości próbkowania powinny zapewniać równowagę między szczegółowością a wydajnością.

zapisywanie danych monitorowanych przez cały dzień,

W przypadku danych zbieranych w ciągłym trybie, takich jak liczba kroków, aplikacja powinna zapisywać dane w Health Connect co najmniej co 15 minut w ciągu dnia.

Typ danych

Jednostka

Oczekiwane

Przykład

Kroki

kroki

Co minutę

23:14 – 23:15 – 5 kroków

23:16 – 23:17 – 22 kroki

23:17 – 23:18 – 8 kroków

Kadencja kroków

kroki/min

Co minutę

23:14 – 23:15 – 5 km/h

23:16 – 23:17 – 22 spm

23:17 – 23:18 – 8 spm

Pchnięcia wózka inwalidzkiego

naciśnięcia

Co minutę

23:14 – 23:15 – 5 push

23:16 – 23:17 – 22 pushe

23:17 – 23:18 – 8 kliknięć

ActiveCaloriesBurned

Kalorie

Co 15 minut

23:15 – 23:30 – 2 kalorie

23:30 – 23:45 – 25 kalorii

23:45 – 00:00 – 5 kalorii

TotalCaloriesBurned

Kalorie

Co 15 minut

23:15 – 23:30 – 16 kalorii

23:30 – 23:45 – 16 kalorii

23:45 – 00:00 – 16 kalorii

Dystans

km/min

Co minutę

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

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

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

Przebyte przewyższenie

min

Co minutę

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

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

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

Zdobyte piętra

piętra

Co minutę

23:14 – 23:15 – 5 pięter

23:16 – 23:16 – 22 piętra

23:17 – 23:18 – 8 pięter

HeartRate

uderz./min

Co minutę

6:11 godz. – 55 uderzeń na minutę

HeartRateVariabilityRmssd

ms

Co minutę

6:11 rano – 23 ms

RespiratoryRate

oddechów/min

Co minutę

23:14 – 23:15 – 60 oddechów na minutę

23:16 - 23:16 - 62 oddechów/minutę

23:17 – 23:18 – 64 oddechy na minutę

OxygenSaturation

%

Co godzinę

6:11 – 95,208%

Zapisuj sesje

Dane powinny być zapisywane w Health Connect po zakończeniu treningu lub sesji snu.

Sprawdzoną metodą jest nagrywanie sesji snu lub ćwiczeń za pomocą urządzenia do nagrywania i odpowiednich metadanych, w tym RecordingMethod.

Aplikacja powinna być zgodna z zaleceniami podanymi w kolumnie „Oczekiwane”. W miarę możliwości postępuj zgodnie z „najlepszymi” wytycznymi.

Dane śledzone podczas ćwiczeń

Typ danych

Jednostka

Oczekiwane

Pozdrawiam

Przykład

Kroki

kroki

Co minutę

Co sekundę

23:14-23:15 – 5 kroków

23:16 – 23:17 – 22 kroki

23:17 – 23:18 – 8 kroków

Kadencja kroków

kroki/min

Co minutę

Co sekundę

23:14-23:15 – 35 spm

23:16 - 23:17 - 37 spm

23:17 – 23:18 – 40 spm

Pchnięcia wózka inwalidzkiego

naciśnięcia

Co minutę

Co sekundę

23:14–23:15 – 5 kliknięć

23:16 – 23:17 – 22 pushe

23:17 – 23:18 – 8 kliknięć

CyclingPedalingCadence

obr./min

Co minutę

Co sekundę

23:14–23:15 – 65 obr./min

23:16 - 23:17 - 70 obr./min

23:17 – 23:18 – 68 obr./min

Moc

waty

Co minutę

Co sekundę

23:14-23:15 – 250 W

23:16 – 23:17 – 255 W

23:17 – 23:18 – 245 W

Szybkość

km/min

Co minutę

Co sekundę

23:14–23:15 – 0,3 km/min

23:16 – 23:17 – 0,4 km/min

23:17 – 23:18 – 0,4 km/min

Dystans

km/m

Co minutę

Co sekundę

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

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

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

ActiveCaloriesBurned

Kalorie

Co minutę

Co sekundę

23:14-23:15 – 20 kalorii

23:16 – 23:17 – 20 kalorii

23:17 – 23:18 – 25 kalorii

TotalCaloriesBurned

Kalorie

Co minutę

Co sekundę

23:14-23:15 – 36 kalorii

23:16 – 23:17 – 36 kalorii

23:17 – 23:18 – 41 kalorii

Przebyte przewyższenie

min

Co minutę

Co sekundę

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

Co 3–5 sekund

Co sekundę

HeartRate

uderz./min

Co minutę

Co sekundę

23:14–23:15 – 150 uderzeń na minutę

23:16 - 23:17 -152 bpm

23:17 – 23:18 – 155 uderzeń na minutę

Dane gromadzone podczas snu

Typ danych

Jednostka

Oczekiwane próbki

Przykład

Etapy snu

etap

szczegółowy okres w poszczególnych fazach snu,

23:46 – 23:50 – przebudzenie

23:50 – 23:56 – sen płytki

23:56 – 00:16 – sen głęboki

RestingHeartRate

uderz./min

pojedyncza wartość dzienna (oczekuje się ją z samego rana);

6:11 godz. – 60 uderzeń na minutę

OxygenSaturation

%

pojedyncza wartość dzienna (oczekuje się ją z samego rana);

6:11 – 95,208%