Schlafeinheiten aufzeichnen

Diese Anleitung ist mit Health Connect-Version 1.1.0-alpha12 oder höher kompatibel.

Health Connect bietet den Datentyp Schlafeinheit, um Informationen zum Schlaf eines Nutzers zu speichern, z. B. eine nächtliche Schlafeinheit oder ein Nickerchen am Tag. Der Datentyp SleepSessionRecord wird verwendet, um diese Sitzungen darzustellen.

Mit Sitzungen können Nutzer die zeitbasierte Leistung über einen bestimmten Zeitraum messen, z. B. kontinuierliche Herzfrequenz- oder Standortdaten.

SleepSessionRecord-Sitzungen enthalten Daten, die Schlafphasen wie AWAKE, SLEEPING und DEEP aufzeichnen.

Untertypdaten sind Daten, die zu einer Trainingseinheit „gehören“ und nur dann sinnvoll sind, wenn sie mit einer übergeordneten Trainingseinheit gelesen werden. Beispiel: Schlafphase.

Verknüpfte Daten hingegen sind Daten, die unabhängig aufgezeichnet werden, aber in den Zeitraum einer Sitzung fallen. Wenn ein Nutzer beispielsweise während einer Schlafeinheit die Herzfrequenz aufzeichnet, sind die Herzfrequenzdaten verknüpfte Daten. Im Gegensatz zu Untertypdaten, die Teil des Sitzungsdatensatzes sind, bestehen verknüpfte Daten aus unabhängigen Datensätzen, die jeweils eine eigene UUID haben.

Verfügbarkeit von Health Connect prüfen

Bevor du versuchst, Health Connect zu verwenden, sollte deine App prüfen, ob Health Connect auf dem Gerät des Nutzers verfügbar ist. Health Connect ist möglicherweise nicht auf allen Geräten vorinstalliert oder deaktiviert. Sie können die Verfügbarkeit mit der Methode HealthConnectClient.getSdkStatus() prüfen.

Verfügbarkeit von Health Connect prüfen

fun checkHealthConnectAvailability(context: Context) {
    val providerPackageName = "com.google.android.apps.healthdata"
    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
}

Je nach dem von getSdkStatus() zurückgegebenen Status kannst du den Nutzer bei Bedarf anleiten, Health Connect aus dem Google Play Store zu installieren oder zu aktualisieren.

Verfügbarkeit der Funktion

Für diesen Datentyp gibt es kein Flag für die Verfügbarkeit von Funktionen.

Erforderliche Berechtigungen

Der Zugriff auf Schlafeinheiten wird durch die folgenden Berechtigungen geschützt:

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

Wenn du deiner App die Funktion für Schlafeinheiten hinzufügen möchtest, musst du zuerst Berechtigungen für den Datentyp SleepSession anfordern.

Hier ist die Berechtigung, die Sie deklarieren müssen, um „Schlafeinheit” schreiben zu können:

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

Wenn du Schlafeinheiten lesen möchtest, musst du die folgenden Berechtigungen anfordern:

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

Berechtigungen vom Nutzer anfordern

Nachdem Sie eine Clientinstanz erstellt haben, muss Ihre App Berechtigungen vom Nutzer anfordern. Nutzer müssen Berechtigungen jederzeit erteilen oder verweigern können. Erstellen Sie dazu eine Reihe von Berechtigungen für die erforderlichen Datentypen. Achte darauf, dass die Berechtigungen in der Gruppe zuerst in deinem Android-Manifest deklariert werden.

val permissions =
    setOf(
        HealthPermission.getReadPermission(SleepSessionRecord::class),
        HealthPermission.getWritePermission(SleepSessionRecord::class)
    )
Mit getGrantedPermissions kannst du prüfen, ob deiner App bereits die erforderlichen Berechtigungen gewährt wurden. Falls nicht, verwenden Sie createRequestPermissionResultContract, um diese Berechtigungen anzufordern. Der Bildschirm mit den Health Connect-Berechtigungen wird angezeigt.
val permissions = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class)
    )

val requestPermissionsLauncher = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { grantedPermissions ->
    if (grantedPermissions.containsAll(permissions)) {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") }
    } else {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") }
    }
}
Da Nutzer Berechtigungen jederzeit erteilen oder widerrufen können, muss deine App vor jeder Verwendung prüfen, ob die Berechtigungen vorhanden sind, und Szenarien verarbeiten, in denen die Berechtigung verloren geht.

Unterstützte Aggregationen

Die folgenden aggregierten Werte sind für SleepSessionRecord verfügbar:

Allgemeine Anleitung

Hier sind einige Best Practices für die Arbeit mit Schlafeinheiten in Health Connect.

  • Sitzungen sollten verwendet werden, um Daten aus einer bestimmten Schlafeinheit hinzuzufügen, für den Schlaf:

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",
                metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH))
            ),
        )
    )
}

  • Untertypdaten müssen in einer Sitzung mit sequenziellen Zeitstempeln, die sich nicht überschneiden, abgeglichen werden. Lücken sind jedoch zulässig.
  • Untertypdaten enthalten keine UUID, aber zugehörige Daten haben eindeutige UUIDs.
  • Sitzungen sind nützlich, wenn der Nutzer möchte, dass Daten mit einer Sitzung verknüpft und als Teil einer Sitzung erfasst werden, anstatt kontinuierlich aufgezeichnet zu werden.

Schlafeinheiten

Sie können Schlafdaten in Health Connect lesen oder schreiben. Schlafdaten werden als Trainingseinheit angezeigt und können in acht verschiedene Schlafphasen unterteilt werden:

  • UNKNOWN: Nicht angegeben oder unbekannt, ob der Nutzer schläft.
  • AWAKE: Der Nutzer ist innerhalb eines Schlafzyklus wach, nicht tagsüber.
  • SLEEPING: Allgemeine oder nicht detaillierte Beschreibung des Schlafs.
  • OUT_OF_BED: Der Nutzer steht mitten in einer Schlafeinheit auf.
  • AWAKE_IN_BED: Der Nutzer ist wach im Bett.
  • LIGHT: Der Nutzer befindet sich in einem Leichtschlafzyklus.
  • DEEP: Der Nutzer befindet sich in einem Tiefschlafzyklus.
  • REM: Der Nutzer befindet sich in einem REM-Schlafzyklus.

Diese Werte stellen die Art des Schlafs dar, den ein Nutzer innerhalb eines Zeitraums hat. Das Schreiben von Schlafphasen ist optional, wird aber empfohlen, falls verfügbar.

Schlafeinheiten schreiben

Der Datentyp SleepSessionRecord besteht aus zwei Teilen:

  1. Die gesamte Schlafphase, die die gesamte Schlafdauer umfasst.
  2. Einzelne Phasen während der Schlafeinheit, z. B. Leichtschlaf oder Tiefschlaf.

So fügst du eine Schlafeinheit ohne Schlafphasen ein:

val zoneRules = ZoneId.systemDefault().rules

// Calculate the specific offset for both start and end times
val startOffset = zoneRules.getOffset(startTime)
val endOffset = zoneRules.getOffset(endTime)

SleepSessionRecord(
    title = "weekend sleep",
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = startOffset,
    endZoneOffset = endOffset,
    metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH))
)

So fügst du Phasen hinzu, die den gesamten Zeitraum einer Schlafeinheit abdecken:

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

Schlafeinheit lesen

Prüfe für jede zurückgegebene Schlafeinheit, ob auch Daten zu Schlafphasen vorhanden sind:

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
}

Schlafeinheit löschen

So löschen Sie eine Sitzung: In diesem Beispiel verwenden wir eine Schlafeinheit:

val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)