Śledzenie sesji snu

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

Health Connect udostępnia typ danych sesja snu, który służy do przechowywania informacji o śnie użytkownika, np. o sesji nocnej lub drzemce w ciągu dnia. Do reprezentowania tych sesji używany jest SleepSessionRecord typ danych.

Sesje umożliwiają użytkownikom pomiar wydajności w określonym czasie, np. ciągłego tętna lub danych o lokalizacji.

Sesje SleepSessionRecord zawierają dane rejestrujące fazy snu, takie jak AWAKE, SLEEPINGDEEP.

Dane podtypu to dane, które „należą” do sesji i mają znaczenie tylko wtedy, gdy są odczytywane z sesją nadrzędną. Na przykład faza snu.

Sprawdzanie dostępności Health Connect

Zanim spróbujesz użyć Health Connect, sprawdź, czy jest on dostępny na urządzeniu użytkownika. Aplikacja Health Connect może nie być wstępnie zainstalowana na wszystkich urządzeniach lub może być wyłączona. Dostępność możesz sprawdzić za pomocą HealthConnectClient.getSdkStatus()metody.

Jak sprawdzić dostępność Health Connect

fun checkHealthConnectAvailability(context: Context) {
    val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME
    val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)

    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
      // Health Connect is not available. Guide the user to install/enable it.
      // For example, show a dialog.
      return // early return as there is no viable integration
    }
    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
      // Health Connect is available but requires an update.
      // Optionally redirect to package installer to find a provider, for example:
      val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
      context.startActivity(
        Intent(Intent.ACTION_VIEW).apply {
          setPackage("com.android.vending")
          data = Uri.parse(uriString)
          putExtra("overlay", true)
          putExtra("callerId", context.packageName)
        }
      )
      return
    }
    // Health Connect is available, obtain a HealthConnectClient instance
    val healthConnectClient = HealthConnectClient.getOrCreate(context)
    // Issue operations with healthConnectClient
}

W zależności od stanu zwróconego przez getSdkStatus() możesz w razie potrzeby poprosić użytkownika o zainstalowanie lub zaktualizowanie Health Connect ze Sklepu Google Play.

Dostępność funkcji

Dla tego typu danych nie ma flagi dostępności funkcji.

Wymagane uprawnienia

Dostęp do sesji snu jest chroniony przez te uprawnienia:

  • android.permission.health.READ_SLEEP
  • android.permission.health.WRITE_SLEEP

Aby dodać do aplikacji funkcję sesji snu, zacznij od poproszenia o uprawnienia do zapisu w przypadku typu danych SleepSession.

Aby móc zapisywać sesje snu, musisz zadeklarować to uprawnienie:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>

Aby odczytać sesję snu, musisz poprosić o te uprawnienia:

<application>
  <uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>

Prośba użytkownika o uprawnienia

Po utworzeniu instancji klienta aplikacja musi poprosić użytkownika o uprawnienia. Użytkownicy muszą mieć możliwość przyznania lub odmowy przyznania uprawnień w dowolnym momencie.

Aby to zrobić, utwórz zestaw uprawnień dla wymaganych typów danych. Sprawdź, czy uprawnienia w zestawie są najpierw zadeklarowane w pliku manifestu Androida.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(SleepSessionRecord::class),
  HealthPermission.getWritePermission(SleepSessionRecord::class)
)

Użyj getGrantedPermissions, aby sprawdzić, czy Twoja aplikacja ma już przyznane wymagane uprawnienia. Jeśli nie, użyj createRequestPermissionResultContract, aby poprosić o te uprawnienia. Wyświetli się ekran uprawnień Health Connect.

// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions successfully granted
  } else {
    // Lack of required permissions
  }
}

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions already granted; proceed with inserting or reading data
  } else {
    requestPermissions.launch(PERMISSIONS)
  }
}

Użytkownicy mogą w dowolnym momencie przyznawać i wycofywać uprawnienia, dlatego aplikacja musi okresowo sprawdzać, czy uprawnienia zostały przyznane, i obsługiwać sytuacje, w których uprawnienia zostaną utracone.

Obsługiwane agregacje

Dostępne są te wartości zagregowane elementu SleepSessionRecord:

Ogólne wskazówki

Oto kilka sprawdzonych metod pracy z sesjami snu w Health Connect.

  • Sesje należy wykorzystywać do dodawania danych z konkretnej sesji snu: w przypadku snu:
suspend fun writeSleepSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            SleepSessionRecord(
                startTime = Instant.parse("2022-05-10T23:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-11T07:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                title = "My Sleep"
            ),
        )
    )
}
  • Sesji nie należy używać do ogólnych pomiarów, takich jak dzienna liczba kroków.
  • Dane podtypu nie zawierają identyfikatora UID, ale powiązane dane mają różne identyfikatory UID.
  • Dane podtypu muszą być dopasowane w sesji z sekwencyjnymi sygnaturami czasowymi, które się nie pokrywają. Dozwolone są jednak przerwy.
  • Sesje są przydatne, jeśli 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

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

  • UNKNOWN: nieokreślony lub nieznany, jeśli użytkownik śpi.
  • AWAKE: użytkownik nie śpi w ciągu cyklu snu, a nie w ciągu dnia.
  • SLEEPING: ogólny lub mało szczegółowy opis snu.
  • OUT_OF_BED: użytkownik wstaje z łóżka w trakcie sesji snu.
  • AWAKE_IN_BED: użytkownik nie śpi i jest w łóżku.
  • LIGHT: użytkownik jest w fazie snu płytkiego.
  • DEEP: użytkownik jest w fazie snu głębokiego.
  • REM: użytkownik jest w fazie snu REM.

Wartości te reprezentują rodzaj snu użytkownika w określonym przedziale czasu. Zapisywanie faz snu jest opcjonalne, ale zalecane, jeśli jest dostępne.

Zapisywanie sesji snu

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

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

Aby wstawić sesję snu bez faz:

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

Oto jak dodać fazy obejmujące 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,
)

Odczytywanie sesji snu

W przypadku każdej zwróconej sesji snu sprawdź, czy są też dostępne dane o fazach 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

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