Dieser Leitfaden ist mit der Health Connect-Version 1.1.0-alpha11 kompatibel.
Health Connect bietet den Datentyp geplante Übung, mit dem Trainings-Apps Trainingspläne erstellen und Trainings-Apps Trainingspläne lesen können. Aufgezeichnete Übungen (Trainings) können für eine personalisierte Leistungsanalyse wiedergegeben werden, um Nutzern zu helfen, ihre Trainingsziele zu erreichen.
Verfügbarkeit der Funktion
Wenn du wissen möchtest, ob das Gerät eines Nutzers Trainingspläne in Health Connect unterstützt, prüfe die Verfügbarkeit von FEATURE_PLANNED_EXERCISE
auf dem Client:
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Feature is available
} else {
// Feature isn't available
}
Weitere Informationen finden Sie unter Verfügbarkeit von Funktionen prüfen.
Erforderliche Berechtigungen
Der Zugriff auf Trainingspläne ist durch die folgenden Berechtigungen geschützt:
android.permission.health.READ_PLANNED_EXERCISE
android.permission.health.WRITE_PLANNED_EXERCISE
Deklarieren Sie diese Berechtigungen in der Play Console für Ihre App und im Manifest Ihrer App:
<application>
<uses-permission
android:name="android.permission.health.READ_PLANNED_EXERCISE" />
<uses-permission
android:name="android.permission.health.WRITE_PLANNED_EXERCISE" />
...
</application>
Sie sind dafür verantwortlich, alle erforderlichen Berechtigungen anzugeben, die Sie auf Ihren Geräten und in Ihren Apps verwenden möchten. Sie sollten außerdem prüfen, ob jede Berechtigung vor der Verwendung vom Nutzer erteilt wurde.
Zugehörige Berechtigungen
Trainingspläne sind mit Trainingseinheiten verknüpft. Daher muss der Nutzer die Verwendung jedes Datensatztyps zulassen, der sich auf einen Trainingsplan bezieht, um diese Funktion von Health Connect vollumfänglich nutzen zu können.
Wenn in einem Trainingsplan beispielsweise die Herzfrequenz eines Nutzers während einer Reihe von Läufen gemessen wird, müssen die folgenden Berechtigungen vom Entwickler deklariert und vom Nutzer gewährt werden, damit die Trainingseinheit aufgezeichnet und die Ergebnisse zur späteren Auswertung gelesen werden können:
android.permission.health.READ_EXERCISE
android.permission.health.READ_EXERCISE_ROUTE
android.permission.health.READ_HEART_RATE
android.permission.health.WRITE_EXERCISE
android.permission.health.WRITE_EXERCISE_ROUTE
android.permission.health.WRITE_HEART_RATE
Oft ist die App, die Trainingspläne erstellt und die Leistung im Vergleich zu den Plänen bewertet, nicht dieselbe wie die App, die Trainingspläne verwendet und tatsächliche Trainingsdaten aufzeichnet. Je nach App sind nicht alle Lese- und Schreibberechtigungen erforderlich. Möglicherweise benötigen Sie für jeden App-Typ nur die folgenden Berechtigungen:
App für Trainingspläne | Trainings-App |
---|---|
WRITE_PLANNED_EXERCISE |
READ_PLANNED_EXERCISE |
READ_EXERCISE |
WRITE_EXERCISE |
READ_EXERCISE_ROUTE |
WRITE_EXERCISE_ROUTE |
READ_HEART_RATE |
WRITE_HEART_RATE |
In einem geplanten Trainingseintrags enthaltene Informationen
- Titel der Sitzung.
- Eine Liste der geplanten Übungsblöcke.
- Start- und Endzeit der Sitzung.
- Trainingstyp
- Notizen zur Aktivität.
- Metadaten
- ID der abgeschlossenen Trainingseinheit: Dieser Wert wird automatisch geschrieben, nachdem eine Trainingseinheit abgeschlossen wurde, die mit dieser geplanten Trainingseinheit verknüpft ist.
Informationen in einem geplanten Trainingsblock
Ein geplanter Übungsblock enthält eine Liste von Übungsschritten, die die Wiederholung verschiedener Schrittgruppen unterstützen. Du kannst beispielsweise eine Abfolge von Armcurls, Burpees und Crunches fünfmal hintereinander ausführen.
- Beschreibung des Blocks.
- Eine Liste der geplanten Übungsschritte.
- Anzahl der Wiederholungen.
Informationen in einem geplanten Trainingsschritt
- Beschreibung des Schritts.
- Trainingskategorie.
- Trainingstyp
- Eine Liste der Leistungsziele.
- Abschlusszielvorhaben.
Unterstützte Aggregationen
Für diesen Datentyp werden keine Aggregationen unterstützt.
Anwendungsbeispiel
Angenommen, ein Nutzer plant einen 90-minütigen Lauf in zwei Tagen. Bei diesem Lauf geht es dreimal um einen See mit einer Zielherzfrequenz zwischen 90 und 110 Schlägen pro Minute.
- Eine geplante Trainingseinheit mit den folgenden Angaben wird vom Nutzer in einer Trainingsplan-App definiert:
- Geplante Laufzeit
- Die Art des Trainings (Laufen)
- Anzahl der Runden (Wiederholungen)
- Leistungsziel für die Herzfrequenz (zwischen 90 und 110 Schlägen pro Minute)
- Diese Informationen werden in Trainingsblöcke und -schritte gruppiert und von der Trainingsplan-App als
PlannedExerciseSessionRecord
in Health Connect geschrieben. - Der Nutzer führt die geplante Sitzung aus (Laufen).
- Trainingsdaten, die sich auf die Sitzung beziehen, werden auf folgende Weise aufgezeichnet:
- Von einem Wearable während der Sitzung Beispiel: Herzfrequenz.
Diese Daten werden als Datensatztyp für die Aktivität in Health Connect gespeichert. In diesem Fall ist das
HeartRateRecord
. - Manuell vom Nutzer nach der Sitzung Geben Sie beispielsweise den Beginn und das Ende des tatsächlichen Laufs an. Diese Daten werden als
ExerciseSessionRecord
in Health Connect geschrieben.
- Von einem Wearable während der Sitzung Beispiel: Herzfrequenz.
Diese Daten werden als Datensatztyp für die Aktivität in Health Connect gespeichert. In diesem Fall ist das
- Später liest die App für den Trainingsplan Daten von Health Connect aus, um die tatsächliche Leistung mit den Zielen zu vergleichen, die der Nutzer in der geplanten Trainingseinheit festgelegt hat.
Übungen planen und Ziele festlegen
Ein Nutzer kann sein Training für die Zukunft planen und Ziele setzen. Speichern Sie diese Daten in Health Connect als geplante Trainingseinheit.
Im Beispiel unter Beispiel für die Verwendung plant der Nutzer einen 90-minütigen Lauf in zwei Tagen. Bei diesem Lauf geht es dreimal um einen See mit einer Zielherzfrequenz zwischen 90 und 110 Schlägen pro Minute.
Ein solches Snippet kann im Formular-Handler einer App gefunden werden, die geplante Trainingseinheiten in Health Connect protokolliert. Sie kann auch am Aufnahmepunkt für Integrationen gefunden werden, z. B. bei einem Dienst, der Schulungen anbietet.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class))) {
// The user hasn't granted the app permission to write planned exercise session data.
return
}
val plannedDuration = Duration.ofMinutes(90)
val plannedStartDate = LocalDate.now().plusDays(2)
val plannedExerciseSessionRecord = PlannedExerciseSessionRecord(
startDate = plannedStartDate,
duration = plannedDuration,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
blocks = listOf(
PlannedExerciseBlock(
repetitions = 1, steps = listOf(
PlannedExerciseStep(
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
exercisePhase = PlannedExerciseStep.EXERCISE_PHASE_ACTIVE,
completionGoal = ExerciseCompletionGoal.RepetitionsGoal(repetitions = 3),
performanceTargets = listOf(
ExercisePerformanceTarget.HeartRateTarget(
minHeartRate = 90.0, maxHeartRate = 110.0
)
)
),
), description = "Three laps around the lake"
)
),
title = "Run at lake",
notes = null
)
val insertedPlannedExerciseSessions =
healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()
Trainings- und Aktivitätsdaten erfassen
Zwei Tage später zeichnet der Nutzer die eigentliche Trainingseinheit auf. Schreibe diese Daten als Trainingseinheit in Health Connect.
In diesem Beispiel stimmte die Sitzungsdauer des Nutzers genau mit der geplanten Dauer überein.
Das folgende Snippet könnte sich im Formular-Handler einer App befinden, die Trainingseinheiten in Health Connect protokolliert. Sie kann auch in Datenaufnahme- und Export-Handlern für ein Wearable verwendet werden, das Trainingseinheiten erkennen und protokollieren kann.
insertedPlannedExerciseSessionId
wird hier aus dem vorherigen Beispiel wiederverwendet. In einer echten App würde die ID festgelegt, wenn der Nutzer eine geplante Trainingseinheit aus einer Liste vorhandener Sitzungen auswählt.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't granted the app permission to write exercise session data.
return
}
val sessionDuration = Duration.ofMinutes(90)
val sessionEndTime = Instant.now()
val sessionStartTime = sessionEndTime.minus(sessionDuration)
val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
segments = listOf(
ExerciseSegment(
startTime = sessionStartTime,
endTime = sessionEndTime,
repetitions = 3,
segmentType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING
)
),
title = "Run at lake",
plannedExerciseSessionId = insertedPlannedExerciseSessionId,
)
val insertedExerciseSessions =
healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
Ein Wearable zeichnet auch die Herzfrequenz während des Laufs auf. Mit dem folgenden Snippet können Sie Einträge im Zielbereich generieren.
In einer echten App befinden sich die wichtigsten Teile dieses Snippets möglicherweise im Handler für eine Nachricht von einem Wearable, die die Messung nach der Erfassung in Health Connect schreibt.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(HeartRateRecord::class))) {
// The user doesn't granted the app permission to write heart rate record data.
return
}
val samples = mutableListOf<HeartRateRecord.Sample>()
var currentTime = sessionStartTime
while (currentTime.isBefore(sessionEndTime)) {
val bpm = Random.nextInt(21) + 90
val heartRateRecord = HeartRateRecord.Sample(
time = currentTime,
beatsPerMinute = bpm.toLong(),
)
samples.add(heartRateRecord)
currentTime = currentTime.plusSeconds(180)
}
val heartRateRecord = HeartRateRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
samples = samples,
)
val insertedHeartRateRecords = healthConnectClient.insertRecords(listOf(heartRateRecord))
Leistungsziele auswerten
Am Tag nach dem Training des Nutzers können Sie das aufgezeichnete Training abrufen, nach geplanten Trainingszielen suchen und zusätzliche Datentypen auswerten, um festzustellen, ob die festgelegten Ziele erreicht wurden.
Ein solches Snippet findet sich wahrscheinlich in einem regelmäßigen Job zur Auswertung von Leistungszielen oder beim Laden einer Liste mit Übungen und dem Einblenden einer Benachrichtigung zu Leistungszielen in einer App.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.containsAll(
listOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class)
)
)
) {
// The user doesn't granted the app permission to read exercise session record data.
return
}
val searchDuration = Duration.ofDays(1)
val searchEndTime = Instant.now()
val searchStartTime = searchEndTime.minus(searchDuration)
val response = healthConnectClient.readRecords(
ReadRecordsRequest<ExerciseSessionRecord>(
timeRangeFilter = TimeRangeFilter.between(searchStartTime, searchEndTime)
)
)
for (exerciseRecord in response.records) {
val plannedExerciseRecordId = exerciseRecord.plannedExerciseSessionId
val plannedExerciseRecord =
if (plannedExerciseRecordId == null) null else healthConnectClient.readRecord(
PlannedExerciseSessionRecord::class, plannedExerciseRecordId
).record
if (plannedExerciseRecord != null) {
val aggregateRequest = AggregateRequest(
metrics = setOf(HeartRateRecord.BPM_AVG),
timeRangeFilter = TimeRangeFilter.between(
exerciseRecord.startTime, exerciseRecord.endTime
),
)
val aggregationResult = healthConnectClient.aggregate(aggregateRequest)
val maxBpm = aggregationResult[HeartRateRecord.BPM_MAX]
val minBpm = aggregationResult[HeartRateRecord.BPM_MIN]
if (maxBpm != null && minBpm != null) {
plannedExerciseRecord.blocks.forEach { block ->
block.steps.forEach { step ->
step.performanceTargets.forEach { target ->
when (target) {
is ExercisePerformanceTarget.HeartRateTarget -> {
val minTarget = target.minHeartRate
val maxTarget = target.maxHeartRate
if(
minBpm >= minTarget && maxBpm <= maxTarget
) {
// Success!
}
}
// Handle more target types
}
}
}
}
}
}
}
}