Sesje

W Health Connect sesja to przedział czasu, w którym użytkownik wykonuje działanie. Zarówno typy danych SleepSessionRecord, jak i ExerciseSessionRecord należą do sesji.

Sesje pozwalają użytkownikom mierzyć wydajność na podstawie czasu w danym okresie, np. przez stałe tętno lub dane o lokalizacji.

Sesje ExerciseSessionRecord obejmują różne aktywności, od biegania po badmintona.

Sesje SleepSessionRecord zawierają dane, które rejestrują fazy snu, np. AWAKE, SLEEPING i DEEP.

Dane podtypu to dane, które „należą” do sesji i mają znaczenie tylko wtedy, gdy są odczytywane razem z sesją rodzica, np. faza snu czy segment ćwiczeń.

Powiązane dane to Record, które można odczytywać oddzielnie lub razem z innymi sesjami, np. kroki, tętno.

Wskazówki ogólne

Oto kilka sprawdzonych metod pracy z sesjami w Health Connect.

  • Sesje powinny służyć do dodawania danych z konkretnego treningu lub konkretnej aktywności albo do monitorowania snu:
suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                exerciseType = ExerciseSessionRecord.ExerciseType.WALKING,
                title = "My Walk"
            ),
            StepsRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 2800
            ),
StepsRecord(
                startTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 3200
            ),  
        )
    )
}
  • Sesji nie należy używać do pomiarów ogólnych, takich jak dzienna liczba kroków.
  • Dane podtypu nie zawierają identyfikatora UID, ale powiązane dane mają różne identyfikatory.
  • Dane podtypu muszą być dopasowane w sesji z sekwencyjnymi sygnaturami czasowymi, które się nie nakładają. Luki są jednak dozwolone.
  • Sesje są przydatne, gdy użytkownik chce, aby dane były powiązane z sesją (i śledzone w jej ramach), a nie rejestrowane w sposób ciągły.

Sesje snu

W Health Connect możesz odczytywać i zapisywać dane dotyczące snu. Dane dotyczące snu są wyświetlane w postaci sesji i można je podzielić na 8 różnych faz snu:

  • UNKNOWN: nie określono lub nie wiadomo, czy użytkownik jest uśpiony.
  • AWAKE: użytkownik nie śpi w trakcie cyklu snu, a nie w ciągu dnia.
  • SLEEPING: ogólny lub nieszczegółowy opis snu.
  • OUT_OF_BED: użytkownik wstaje w trakcie sesji snu.
  • AWAKE_IN_BED: użytkownik nie śpi.
  • LIGHT: użytkownik jest w fazie płytkiego snu.
  • DEEP: użytkownik jest w fazie snu głębokiego.
  • REM: użytkownik jest w fazie snu REM.

Te wartości reprezentują rodzaj snu u użytkownika w danym okresie. Zapisywanie faz snu jest opcjonalne, ale zalecane, jeśli to możliwe.

Zapisuj dane o sesjach snu z fazami snu lub bez nich

Typ danych SleepSessionRecord składa się z 2 części:

  1. Cała sesja obejmująca cały czas snu.
  2. Poszczególne fazy sesji snu, takie jak sen płytki czy sen głęboki.

Oto jak wprowadzić sesję snu bez faz:

      SleepSessionRecord(
        title = "weekend sleep",
        startTime = startTime,
        endTime = endTime,
        startZoneOffset = ZoneOffset.UTC,
        endZoneOffset = ZoneOffset.UTC,
      )

Aby dodać fazy, które obejmują cały okres sesji snu:

val stages = listOf(
    SleepSessionRecord.Stage(
        startTime = START_TIME
        endTime = END_TIME,
        stage = SleepSessionRecord.STAGE_TYPE_SLEEPING,
    )
)

SleepSessionRecord(
        title = "weekend sleep",
        startTime = START_TIME,
        endTime = END_TIME,
        startZoneOffset = START_ZONE_OFFSET,
        endZoneOffset = END_ZONE_OFFSET,
        stages = stages,
      )
  }

Odczytuj dane o sesji snu

W przypadku każdej zwróconej sesji snu musisz sprawdzić, czy są w nim też dostępne dane o fazie snu:

suspend fun readSleepSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                SleepSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (sleepRecord in response.records) {
        // Retrieve relevant sleep stages from each sleep record
        val sleepStages = sleepRecord.stages
    }
}

Usuwanie sesji snu

Tutaj dowiesz się, jak usunąć sesję. W tym przykładzie użyliśmy sesji snu:

suspend fun deleteSleepSession(
    healthConnectClient: HealthConnectClient,
    sleepRecord: SleepSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
}

Sesje ćwiczeń

Sesje ćwiczeń mogą obejmować wszystko, od biegania po badmintona.

Zapisuj dane o sesjach ćwiczeń

Aby utworzyć żądanie reklamy, które zawiera sesję:

suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                exerciseType = ExerciseSessionRecord.ExerciseType.RUNNING,
                title = "My Run"
            ),
            DistanceRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                distance = 5000.meters
            ),
            // ... other records
        )
    )
}

Zwróć uwagę, jak w poprzednim przykładzie dodawany jest rekord dla Distance, który obejmuje cały czas trwania sesji, ale dane można dodawać z różną szczegółowością.

Jeśli aplikacja regularnie mierzy dystans podczas biegu, inną metodą jest dodanie wielu rekordów dystansu, z których każdy reprezentuje pokonany dystans podczas biegu.

Odczytuj dane o sesji ćwiczeń

Oto przykład, jak odczytywać dane z sesji ćwiczeń:

suspend fun readExerciseSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                ExerciseSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (exerciseRecord in response.records) {
        // Process each exercise record
        // Optionally pull in with other data sources of the same time range.
        val distanceRecord =
            healthConnectClient
                .readRecords(
                    ReadRecordsRequest(
                        DistanceRecord::class,
                        timeRangeFilter =
                            TimeRangeFilter.between(
                                exerciseRecord.startTime,
                                exerciseRecord.endTime
                            )
                    )
                )
                .records
    }
}

Zapisz dane podtypu

Sesje mogą też składać się z nieobowiązkowych podtypów danych, które wzbogacają sesję o dodatkowe informacje.

Na przykład sesje ćwiczeń mogą obejmować klasy ExerciseSegment, ExerciseLap i ExerciseRoute:

val segments = listOf(
  ExerciseSegment(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    segmentType = ActivitySegmentType.BENCH_PRESS,
    repetitions = 373
  )
)

val laps = listOf(
  ExerciseLap(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    length = 0.meters
  )
)

ExerciseSessionRecord(
  exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS,
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
  startZoneOffset = ZoneOffset.UTC,
  endZoneOffset = ZoneOffset.UTC,
  segments = segments,
  laps = laps,
  route = route
)

Usuwanie sesji ćwiczeń

Sesja ćwiczeń można usunąć na 2 sposoby:

  1. Według zakresu czasu.
  2. Według identyfikatora UID.

Aby usunąć dane podtypów na podstawie zakresu czasu:

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
    // delete the associated distance record
    healthConnectClient.deleteRecords(DistanceRecord::class, timeRangeFilter)
}

Możesz też usuwać dane podtypów według identyfikatora UID. Spowoduje to jednak usunięcie tylko sesji ćwiczenia, a nie powiązanych danych.

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    healthConnectClient.deleteRecords(
        ExerciseSessionRecord::class,
        recordIdsList = listOf(exerciseRecord.metadata.id),
        clientRecordIdsList = emptyList()
    )
}