Wenn Sie eine Funktion zur Schlaferfassung in Ihre App einbauen möchten, können Sie mit Health Connect Folgendes tun:
- Schlafeinheiten schreiben
- Daten zu Schlafphasen schreiben
- Schlafdaten wie Herzfrequenz, Sauerstoffsättigung und Atemfrequenz schreiben
- Schlafdaten aus anderen Apps lesen
In dieser Anleitung wird beschrieben, wie Sie diese Schlaffunktionen erstellen. Dabei werden Datentypen, Hintergrundausführung, Berechtigungen, empfohlene Workflows und Best Practices behandelt.
Übersicht: Umfassende Schlaferfassung erstellen
Mit Health Connect können Sie eine umfassende Schlaferfassung erstellen. Dazu sind folgende Schritte erforderlich:
- Berechtigungen basierend auf Health-Berechtigungen korrekt implementieren.
- Sitzungen mit
SleepSessionRecordaufzeichnen. - Datentypen wie Schlafphasen, Herzfrequenz und Sauerstoffsättigung während der Sitzung einheitlich schreiben.
- Hintergrundausführung richtig verwalten, um die kontinuierliche Datenerfassung über Nacht zu überprüfen.
- Sitzungsdaten für Zusammenfassungen und Analysen nach dem Schlaf lesen.
Dieser Workflow ermöglicht die Interoperabilität mit anderen Health Connect-Apps und überprüft den nutzergesteuerten Datenzugriff.
Hinweis
Bevor Sie Schlaffunktionen implementieren:
- Health Connect mit der entsprechenden Abhängigkeit einbinden.
- Eine
HealthConnectClient-Instanz erstellen. - Prüfen, ob Ihre App LaufzeitBerechtigungsabläufe basierend auf Health Berechtigungen implementiert.
Schlüsselkonzepte
Health Connect stellt Schlafdaten mit einigen Kernkomponenten dar. SleepSessionRecord dient als zentraler Eintrag für den Schlaf und enthält Details wie Start- und Endzeiten sowie Schlafphasen. Während einer Sitzung können verschiedene Datentypen wie HeartRateRecord oder OxygenSaturationRecord aufgezeichnet werden.
Schlafeinheiten
Schlafdaten werden durch SleepSessionRecord dargestellt. Jeder Eintrag speichert Folgendes:
startTimeendTimestages: Eine Liste vonSleepSessionRecord.Stage, einschließlich Tiefschlaf, leichter Schlaf, REM-Schlaf und Wachphasen.- Optionale Sitzungsmetadaten (Titel, Notizen)
Apps können mehrere Datentypen schreiben, die mit einer Sitzung verknüpft sind.
Datentypen
Zu den gängigen Datentypen, die während einer Schlafeinheit aufgezeichnet werden, gehören:
SleepSessionRecord: Erfasst die Schlafdauer und ‑phasen, einschließlich Tiefschlaf, leichter Schlaf, REM-Schlaf und Wachphasen.HeartRateRecord: Erfasst die Herzfrequenz während des Schlafs.OxygenSaturationRecord: Erfasst die Sauerstoffsättigung (SpO2) während des Schlafs.RespiratoryRateRecord: Erfasst die Atemfrequenz während des Schlafs.
Jeder Datentyp wird als einzelner Eintrag gespeichert.
Überlegungen zur Entwicklung
Apps zur Schlaferfassung müssen oft über längere Zeiträume ausgeführt werden, häufig im Hintergrund, wenn der Bildschirm ausgeschaltet ist. Wenn Sie Ihre Schlaffunktionen erstellen, ist es wichtig, zu überlegen, wie Sie die Hintergrundausführung verwalten und die erforderlichen Berechtigungen für Schlafdaten anfordern.
Ausführung im Hintergrund
Apps zur Schlaferfassung werden in der Regel über Nacht ausgeführt, wenn der Bildschirm ausgeschaltet ist. In diesem Fall sollten Sie Folgendes verwenden:
- Dienste im Vordergrund für die Datenerfassung
WorkManagerfür verzögertes Schreiben oder Synchronisieren- Batching-Strategien für regelmäßige Schreibvorgänge von detaillierten Daten wie der Herzfrequenz
Sorgen Sie für Kontinuität, indem Sie die Sitzungs-ID bei allen Schreibvorgängen einheitlich verwenden.
Berechtigungen
Ihre App muss die entsprechenden Health Connect-Berechtigungen anfordern, bevor sie Schlafdaten lesen oder schreiben kann. Eine vollständige Liste der Datentypen finden Sie unter Health Connect-Datentypen. Zu den gängigen Berechtigungen für den Schlaf gehören Schlafeinheiten und Messwerte wie Herzfrequenz oder Sauerstoffsättigung.
Der Zugriff auf Schlafdaten wird durch die folgenden Berechtigungen geschützt:
android.permission.health.READ_SLEEPandroid.permission.health.WRITE_SLEEP
Wenn Sie Ihrer App Schlaffunktionen hinzufügen möchten, fordern Sie zuerst Berechtigungen für den Datentyp SleepSession an.
Hier ist die Berechtigung, die Sie deklarieren müssen, um Schlafdaten schreiben zu können:
<application>
<uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>
Wenn Sie Schlafdaten lesen möchten, müssen Sie die folgenden Berechtigungen anfordern:
<application>
<uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>
Im Folgenden sehen Sie ein Beispiel dafür, wie Sie Berechtigungen für eine Schlafeinheit anfordern, die Daten zur Herzfrequenz, Sauerstoffsättigung und Atemfrequenz enthält:
Nachdem Sie eine Client-Instanz erstellt haben, muss Ihre App Berechtigungen vom Nutzer anfordern. Nutzer müssen jederzeit Berechtigungen erteilen oder verweigern können.
Erstellen Sie dazu eine Reihe von Berechtigungen für die erforderlichen Datentypen. Achten Sie darauf, dass die Berechtigungen im Set zuerst in Ihrem Android-Manifest deklariert werden.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(OxygenSaturationRecord::class),
HealthPermission.getWritePermission(OxygenSaturationRecord::class),
HealthPermission.getReadPermission(RespiratoryRateRecord::class),
HealthPermission.getWritePermission(RespiratoryRateRecord::class)
)
Mit getGrantedPermissions können Sie prüfen, ob Ihrer App bereits die
erforderlichen Berechtigungen gewährt wurden. Falls nicht, fordern Sie diese Berechtigungen mit
createRequestPermissionResultContract an. Daraufhin wird der Bildschirm mit den Health Connect-Berechtigungen angezeigt.
// 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)
}
}
Da Nutzer Berechtigungen jederzeit erteilen oder widerrufen können, muss Ihre App jedes Mal vor der Verwendung von Berechtigungen prüfen, ob sie vorhanden sind, und Szenarien berücksichtigen, in denen Berechtigungen verloren gehen.
Schlafeinheit implementieren
In diesem Abschnitt wird der empfohlene Workflow zum Aufzeichnen von Schlafdaten beschrieben.
Um Datentypen wie HeartRateRecord oder OxygenSaturationRecord mit einer Schlafeinheit abzugleichen, zeichnen Sie sie mit Zeitstempeln auf, die zwischen startTime und endTime der Sitzung liegen. Health Connect verwendet keine Sitzungs-ID, um Schlafeinheiten mit detaillierten Daten zu verknüpfen. Stattdessen erfolgt die Zuordnung implizit durch überlappende Zeitintervalle. Wenn Sie Schlafdaten lesen, können Sie den Zeitraum einer Sitzung
verwenden, um nach verknüpften Datentypen zu suchen. Weitere Informationen finden Sie unter
Schlafdaten lesen.
Sitzung schreiben
Während einer Schlafeinheit können detaillierte Daten wie die Herzfrequenz aufgezeichnet werden. Der SleepSessionRecord selbst darf jedoch erst in Health Connect geschrieben werden, wenn die Sitzung beendet ist, z. B. wenn der Nutzer aufwacht. Der
Eintrag muss
die Sitzung startTime, endTime und eine Liste der während der Sitzung aufgezeichneten SleepSessionRecord.Stage
Objekte enthalten, da für SleepSessionRecord gilt, dass endTime
nach startTime liegen muss.
So schreiben Sie eine Schlafeinheit:
- Generieren Sie eine eindeutige Client-Eintrags-ID.
- Wenn der Nutzer aufwacht oder die Schlaferfassung beendet wird, erfassen Sie alle Schlafphasen und erstellen Sie einen
SleepSessionRecord. - Fügen Sie den Eintrag mit
insertRecordsein.
Beispiel:
val clientRecordId = UUID.randomUUID().toString()
val sessionStartTime = LocalDateTime.of(2023, 10, 30, 22, 0).toInstant(ZoneOffset.UTC)
val sessionEndTime = LocalDateTime.of(2023, 10, 31, 7, 0).toInstant(ZoneOffset.UTC)
val stages = mutableListOf<SleepSessionRecord.Stage>()
// Add recorded stages, for example:
stages.add(SleepSessionRecord.Stage(
startTime = sessionStartTime.plusSeconds(3600),
endTime = sessionStartTime.plusSeconds(7200),
stage = SleepSessionRecord.STAGE_TYPE_LIGHT)
)
stages.add(SleepSessionRecord.Stage(
startTime = sessionStartTime.plusSeconds(7200),
endTime = sessionStartTime.plusSeconds(10800),
stage = SleepSessionRecord.STAGE_TYPE_DEEP)
)
// ... other stages
val session = SleepSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
stages = stages,
metadata = Metadata(clientRecordId = clientRecordId)
)
healthConnectClient.insertRecords(listOf(session))
Schlafdaten lesen
Apps können Schlafeinheiten und die zugehörigen Daten lesen, um Aktivitäten zusammenzufassen, Gesundheitsinformationen zu liefern oder Daten mit einem externen Server zu synchronisieren. Sie können beispielsweise einen SleepSessionRecord lesen und dann die HeartRateRecord abfragen, die im selben Zeitraum aufgezeichnet wurde.
Sitzung mit zugehörigen Daten lesen
Sie können Schlafeinheiten mit einer ReadRecordsRequest lesen, wobei SleepSessionRecord als Eintragstyp verwendet wird und nach einem Zeitraum gefiltert wird. Wenn Sie zugehörige Daten für eine bestimmte Sitzung lesen möchten, stellen Sie eine zweite Anfrage für den ausgewählten Datentyp, z. B. HeartRateRecord, und filtern Sie nach startTime und endTime der Schlafeinheit.
Im folgenden Beispiel wird gezeigt, wie Sie Schlafeinheiten mit zugehörigen Herzfrequenzdaten für einen bestimmten Zeitraum lesen:
suspend fun readSleepSessionsWithAssociatedData(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = SleepSessionRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (sleepRecord in response.records) {
// Process each session
val stages = sleepRecord.stages
val notes = sleepRecord.notes
// To read specific granular data (like heart rate) that occurred during
// this session, use the session's startTime and endTime to filter
// the request for that data type.
val hrResponse = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(
sleepRecord.startTime,
sleepRecord.endTime
)
)
)
for (heartRateRecord in hrResponse.records) {
for (sample in heartRateRecord.samples) {
val bpm = sample.beatsPerMinute
}
}
}
}
Best Practices
Beachten Sie diese Richtlinien, um die Zuverlässigkeit der Daten und die Nutzerfreundlichkeit zu verbessern:
- Schreibhäufigkeit
- Aktive Erfassung(Vordergrund) : Schreiben Sie bei der aktiven Schlaferfassung Daten, sobald sie verfügbar sind, oder in einem maximalen Intervall von 15 Minuten.
- Hintergrundsynchronisierung:Verwenden Sie
WorkManagerfür verzögerte Schreibvorgänge. Ein Intervall von 15 Minuten ist ein guter Kompromiss zwischen Echtzeitdaten und Akkueffizienz. - Batching:Schreiben Sie nicht jedes einzelne Sensorereignis einzeln. Chunk-Anfragen verwenden. Health Connect verarbeitet bis zu 1.000 Einträge pro Schreibanfrage.
- Sitzungs-IDs stabil und eindeutig halten:Verwenden Sie einheitliche IDs für Ihre Sitzungen. Wenn eine Sitzung bearbeitet oder aktualisiert wird, wird sie durch die Verwendung derselben ID nicht als neue, separate Schlafeinheit behandelt.
- Batching für Datentypen verwenden:Um den Input/Output-Overhead zu reduzieren und die Akkulaufzeit zu verlängern, gruppieren Sie Ihre Datenpunkte in einem einzigen
insertRecords-Aufruf, anstatt jeden Punkt einzeln zu schreiben. Doppelte Daten vermeiden: Client-IDs verwenden Wenn Sie Einträge erstellen, legen Sie eine
metadata.clientRecordIdfest. Health Connect verwendet diese ID, um eindeutige Einträge zu identifizieren. Wenn Sie versuchen, einen Eintrag mit einer bereits vorhandenenclientRecordIdzu schreiben, ignoriert Health Connect das Duplikat oder aktualisiert den vorhandenen Eintrag, anstatt einen neuen zu erstellen. Das Festlegen einermetadata.clientRecordIdist die effektivste Methode, um Duplikate bei Synchronisierungsversuchen oder Neuinstallationen von Apps zu vermeiden.val record = RespiratoryRateRecord( rate = 16.0, time = time, zoneOffset = ZoneOffset.UTC, metadata = Metadata( // Use a unique ID from your own database clientRecordId = "respiratory_rate_20231030_1" ) )Vorhandene Daten prüfen:Fragen Sie vor der Synchronisierung den Zeitraum ab, um zu prüfen, ob bereits Einträge aus Ihrer App vorhanden sind.
Zeitstempel dürfen sich nicht überschneiden:Prüfen Sie, ob eine neue Sitzung erst beginnt, nachdem die vorherige beendet wurde. Überlappende Sitzungen können zu Konflikten in Fitness-Dashboards und bei Zusammenfassungsberechnungen führen.
Berechtigungen klar begründen:Verwenden Sie den
Permission.createIntent-Ablauf, um zu erklären, warum Ihre App Zugriff auf Gesundheitsdaten benötigt, z. B. „Um Ihre Schlafmuster zu analysieren“.Lange Sitzungen testen:Überwachen Sie den Akkuverbrauch bei Sitzungen, die mehrere Stunden dauern, um zu prüfen, ob das Batching-Intervall und die Sensornutzung den Akku nicht zu stark belasten.
Zeitstempel an Sensorraten anpassen:Passen Sie die Zeitstempel Ihrer Einträge an die tatsächliche Frequenz Ihrer Sensoren an, um eine hohe Datentreue zu gewährleisten.
Testen
Um die Richtigkeit der Daten und eine hohe Nutzerfreundlichkeit zu gewährleisten, folgen Sie diesen Teststrategien und lesen Sie die offizielle Dokumentation zu den wichtigsten Anwendungsfällen für Tests.
Tools zur Überprüfung
- **Health Connect Toolbox**: Mit dieser Begleit-App können Sie Einträge manuell prüfen, Testdaten löschen und Änderungen an der Datenbank simulieren. So lässt sich am besten prüfen, ob Ihre Einträge korrekt gespeichert werden.
- Unit-Tests mit
FakeHealthConnectClient: Mit der Testbibliothek können Sie prüfen, wie Ihre App Grenzfälle wie den Widerruf von Berechtigungen oder API Ausnahmen behandelt, ohne dass ein physisches Gerät erforderlich ist.
Checkliste für Qualität
Typische Architektur
Eine Implementierung zur Schlaferfassung umfasst in der Regel Folgendes:
| Komponente | Verwaltet |
|---|---|
| Sitzungscontroller | Sitzungsstatus Timer Batching-Logik Controller für Datentypen Datenerfassung |
| Repository-Ebene (fasst Health Connect-Vorgänge zusammen): | Sitzung einfügen Datentypen einfügen Schlafphasen einfügen Sitzungszusammenfassungen lesen |
| UI-Ebene (zeigt Folgendes an): | Dauer Live-Datentypen Visualisierung der Schlafphasen |
Fehlerbehebung
| Symptom | Mögliche Ursache | Lösung |
|---|---|---|
| Fehlende Datentypen (z. B. Herzfrequenz) | Fehlende Schreibberechtigungen oder falsche Zeitfilter. | Prüfen Sie, ob Sie die Berechtigung für den jeweiligen Datentyp angefordert haben und ob der Nutzer sie erteilt hat. Prüfen Sie, ob Ihre ReadRecordsRequest einen TimeRangeFilter verwendet, der mit der Sitzung übereinstimmt. Weitere Informationen finden Sie unter Berechtigungen. |
| Sitzung kann nicht geschrieben werden | Überlappende Zeitstempel. | Health Connect lehnt möglicherweise Einträge ab, die sich mit vorhandenen Daten aus derselben App überschneiden. Prüfen Sie, ob die startTime einer neuen Sitzung nach der endTime der vorherigen Sitzung liegt. |
| Während des Schlafs werden keine Sensordaten aufgezeichnet | Der Dienst im Vordergrund wurde beendet oder ist inaktiv. | Wenn Sie über Nacht Sensordaten erfassen möchten, während der Bildschirm ausgeschaltet ist, können Sie einen Dienst im Vordergrund mit foregroundServiceType="health" verwenden. |
| Doppelte Einträge werden angezeigt | clientRecordId fehlt. |
Weisen Sie in den Metadata jedes Eintrags eine eindeutige clientRecordId zu. So kann Health Connect Duplikate entfernen, wenn dieselben Daten bei einem Synchronisierungsversuch zweimal geschrieben werden. Weitere Informationen finden Sie unter Best Practices. |
Allgemeine Schritte zur Fehlerbehebung
| Berechtigungsstatus prüfen. | Rufen Sie immer getPermissionStatus() auf, bevor Sie einen Lese- oder Schreibvorgang ausführen. Nutzer können Berechtigungen jederzeit in den Systemeinstellungen widerrufen. |
| Ausführungsmodus prüfen. | Wenn Ihre App keine Daten im Hintergrund erfasst, prüfen Sie, ob Sie die richtigen Berechtigungen in Ihrer AndroidManifest.xml-Datei deklariert haben und ob der Nutzer die App nicht in den Modus „Akkunutzung eingeschränkt“ versetzt hat. |