Diese Anleitung ist mit Health Connect-Version 1.1.0-alpha12 kompatibel.
Mit Trainingsrouten können Nutzer eine GPS-Route für zugehörige Trainingsaktivitäten aufzeichnen und Karten ihrer Trainings mit anderen Apps teilen.
Verfügbarkeit der Funktion
So prüfen Sie, ob das Gerät eines Nutzers Trainingsrouten in Health Connect unterstützt:FEATURE_PLANNED_EXERCISE
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Feature is available
} else {
// Feature isn't available
}
In dieser Anleitung erfahren Sie, wie Sie Berechtigungen vom Nutzer anfordern und wie Apps die Berechtigung zum Schreiben von Routendaten im Rahmen einer Trainingseinheit erhalten.
Die Lese- und Schreibfunktionen für Trainingsrouten umfassen:
- Apps erstellen eine neue Schreibberechtigung für Trainingsrouten.
- Das Einfügen erfolgt durch Schreiben einer Trainingseinheit mit einer Route als Feld.
- Lesen:
- Für den Sitzungsinhaber wird über einen Sitzungslesevorgang auf Daten zugegriffen.
- Über eine Drittanbieter-App über ein Dialogfeld, in dem der Nutzer das einmalige Lesen einer Route zulassen kann.
Wenn der Nutzer keine Schreibberechtigungen hat und die Route nicht festgelegt ist, wird sie nicht aktualisiert.
Wenn Ihre App die Berechtigung zum Schreiben von Routen hat und versucht, eine Sitzung zu aktualisieren, indem sie ein Sitzungsobjekt ohne Route übergibt, wird die vorhandene Route gelöscht.
Erforderliche Berechtigungen
Der Zugriff auf die Trainingsroute ist durch die folgenden Berechtigungen geschützt:
android.permission.health.READ_EXERCISE_ROUTE
android.permission.health.WRITE_EXERCISE_ROUTE
Wenn Sie Ihrer App die Funktion zum Hinzufügen von Trainingsrouten hinzufügen möchten, müssen Sie zuerst Schreibberechtigungen für den Datentyp ExerciseSession
anfordern.
Hier ist die Berechtigung, die Sie deklarieren müssen, um Trainingsrouten schreiben zu können:
<application>
<uses-permission
android:name="android.permission.health.WRITE_EXERCISE_ROUTE" />
...
</application>
Wenn Sie Trainingsrouten lesen möchten, müssen Sie die folgenden Berechtigungen anfordern:
<application>
<uses-permission
android:name="android.permission.health.READ_EXERCISE_ROUTE" />
...
</application>
Außerdem müssen Sie eine Berechtigung für Training deklarieren, da jede Route mit einer Trainingseinheit verknüpft ist (eine Einheit = ein Training).
Verwenden Sie die Methode PermissionController.createRequestPermissionResultContract()
, wenn Sie Ihre App zum ersten Mal mit Health Connect verbinden, um Berechtigungen anzufordern. Hier sind einige Berechtigungen, die Sie möglicherweise anfordern möchten:
- Gesundheitsdaten, einschließlich Routendaten, lesen:
HealthPermission.getReadPermission(ExerciseSessionRecord::class)
- Gesundheitsdaten, einschließlich Routendaten, schreiben:
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
- Daten zur Trainingsroute schreiben:
HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE
Berechtigungen vom Nutzer anfordern
Nachdem Sie eine Client-Instanz erstellt haben, muss Ihre App Berechtigungen vom Nutzer anfordern. Nutzer müssen jederzeit die Möglichkeit haben, Berechtigungen zu erteilen oder zu verweigern.
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(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
Mit getGrantedPermissions
können Sie prüfen, ob Ihrer App bereits die erforderlichen Berechtigungen erteilt wurden. Falls nicht, verwenden Sie createRequestPermissionResultContract
, um diese Berechtigungen anzufordern. Dadurch 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 regelmäßig prüfen, welche Berechtigungen erteilt wurden, und Szenarien berücksichtigen, in denen Berechtigungen verloren gehen.
In einem Trainingsaufzeichnung enthaltene Informationen
Jeder Trainingssitzungseintrag enthält die folgenden Informationen:
- Die Trainingsart, z. B. Radfahren.
- Die Trainingsroute, die Informationen wie Breitengrad, Längengrad und Höhe enthält.
Unterstützte Aggregationen
Für diesen Datentyp sind keine unterstützten Aggregationen vorhanden.
Beispiel für die Verwendung
Eine Route anfordern oder eine Route aus einer Sitzung erstellen
Route aus einer Sitzung anfordern
So lesen Sie eine Trainingseinheit in Health Connect und fordern eine Route für diese Trainingseinheit an:
suspend fun readExerciseSessionAndRoute() {
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofHours(1))
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getReadPermission(ExerciseSessionRecord::class))) {
// The user doesn't allow the app to read exercise session data.
return
}
val readResponse =
healthConnectClient.readRecords(
ReadRecordsRequest(
ExerciseSessionRecord::class,
TimeRangeFilter.between(startTime, endTime)
)
)
val exerciseRecord = readResponse.records.first()
val recordId = exerciseRecord.metadata.id
// See https://developer.android.com/training/basics/intents/result#launch
// for appropriately handling ActivityResultContract.
val requestExerciseRouteLauncher = fragment.registerForActivityResul
(ExerciseRouteRequestContract()) { exerciseRoute: ExerciseRoute? ->
if (exerciseRoute != null) {
displayExerciseRoute(exerciseRoute)
} else {
// Consent was denied
}
}
val exerciseSessionRecord =
healthConnectClient.readRecord(ExerciseSessionRecord::class, recordId).record
when (val exerciseRouteResult = exerciseSessionRecord.exerciseRouteResult) {
is ExerciseRouteResult.Data ->
displayExerciseRoute(exerciseRouteResult.exerciseRoute)
is ExerciseRouteResult.ConsentRequired ->
requestExerciseRouteLauncher.launch(recordId)
is ExerciseRouteResult.NoData -> Unit // No exercise route to show
else -> Unit
}
}
fun displayExerciseRoute(route: ExerciseRoute?) {
val locations = route.route.orEmpty()
for (location in locations) {
// Handle location.
}
}
Route aus einer Sitzung erstellen
Der folgende Code zeigt, wie Sie eine Trainingseinheit mit einer Trainingsstrecke aufzeichnen:
suspend fun InsertExerciseRoute(healthConnectClient: HealthConnectClient) {
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't allow the app to write exercise session data.
return
}
val sessionStartTime = Instant.now()
val sessionDuration = Duration.ofMinutes(20)
val sessionEndTime = sessionStartTime.plus(sessionDuration)
val exerciseRoute =
if (grantedPermissions.contains(PERMISSION_WRITE_EXERCISE_ROUTE)) ExerciseRoute(
listOf(
ExerciseRoute.Location(
// Location times must be on or after the session start time
time = sessionStartTime,
latitude = 6.5483,
longitude = 0.5488,
horizontalAccuracy = Length.meters(2.0),
verticalAccuracy = Length.meters(2.0),
altitude = Length.meters(9.0),
), ExerciseRoute.Location(
// Location times must be before the session end time
time = sessionEndTime.minusSeconds(1),
latitude = 6.4578,
longitude = 0.6577,
horizontalAccuracy = Length.meters(2.0),
verticalAccuracy = Length.meters(2.0),
altitude = Length.meters(9.2),
)
)
)
else
// The user doesn't allow the app to write exercise route data.
null
val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
title = "Morning Bike Ride",
exerciseRoute = exerciseRoute,
metadata = Metadata.manualEntry(
device = Device(type = Device.TYPE_PHONE)
),
)
val response = healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
}