Trainingsrouten hinzufügen

Trainingsrouten ermöglichen es Nutzern, eine GPS-Route für zugehörige Trainingsaktivitäten zu verfolgen und Karten ihrer Trainingseinheiten mit anderen Apps zu teilen.

In dieser Anleitung wird beschrieben, wie Apps im Rahmen einer Trainingssitzung die Berechtigung zum Schreiben von Routendaten erhalten.

Hier ist eine kurze Zusammenfassung der Lese- und Schreibfunktion für Trainingsrouten:

  1. Apps erstellen eine neue Schreibberechtigung für Trainingsrouten.
  2. Das Einfügen erfolgt durch Schreiben einer Trainingssitzung mit einer Route als Feld.
  3. Lesematerialien:
    1. Für den Sitzungsinhaber erfolgt der Zugriff auf die Daten über einen Sitzungslesevorgang.
    2. In einer Drittanbieter-App über ein Dialogfeld, in dem der Nutzer das einmalige Lesen einer Route erlauben kann.

Berechtigungen

Trainingsrouten haben eine eigene Schreibberechtigung für die Laufzeit (android.permission.health.WRITE_EXERCISE_ROUTE).

Wenn Sie Ihrer Anwendung eine Trainingsroutenfunktion hinzufügen möchten, fordern Sie zuerst Schreibberechtigungen für einen bestimmten Datentyp an.

Berechtigungsanfrage für Android 14

Berechtigungsanfrage für Android 14

Berechtigungsanfrage für Android 13

Berechtigungsanfrage für Android 13

Außerdem müssen Sie eine Trainingsberechtigung erklären, da jede Route einer Trainingssitzung zugeordnet ist (eine Sitzung = eine Training).

Du musst die folgende Berechtigung erklären, um Trainingsrouten schreiben zu können:

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

Um Trainingsrouten zu lesen, musst du die folgenden Berechtigungen anfordern:

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

Verwenden Sie zum Anfordern von Berechtigungen die Methode PermissionController.createRequestPermissionResultContract(), wenn Sie Ihre App zum ersten Mal mit Health Connect verbinden. Sie können verschiedene Berechtigungen anfordern:

  • Zustandsdaten lesen, einschließlich Routendaten: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Zustandsdaten schreiben, einschließlich Routendaten: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Trainingsroutendaten schreiben: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Routendaten lesen und schreiben

Anwendungen fügen eine Route ein, indem sie eine Sitzung mit einer Route als Feld schreiben.

Wenn der Nutzer keine Schreibberechtigungen hat und die Route nicht festgelegt ist, wird sie nicht aktualisiert.

Wenn Ihre Anwendung eine Schreibberechtigung für Routen hat und versucht, eine Sitzung durch Übergabe eines Sitzungsobjekts ohne Route zu aktualisieren, wird die vorhandene Route gelöscht.

Immer wenn Ihre Anwendung Routendaten einer Drittanbieter-App lesen muss, wird ein Dialogfeld angezeigt, in dem der Nutzer aufgefordert wird, den Lesevorgang zuzulassen.

Route aus einer Sitzung anfordern

So lesen Sie eine Sitzung in Health Connect und fordern eine Route von dieser Sitzung an:

suspend fun readExerciseSessionAndRoute() {
    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()

    // 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 schreiben

Der folgende Code zeigt, wie eine Sitzung mit einer Trainingsroute aufgezeichnet wird:

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.parse("2023-01-01T10:00:00.00Z")
    val sessionDuration = Duration.ofMinutes(20)

    val exerciseRoute =
      if (getPermissions.contains(PERMISSION_EXERCISE_ROUTE_WRITE) {
        ExerciseRoute(
          listOf(
            ExerciseRoute.Location(
              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(
              time = sessionStartTime.plus(sessionDuration)
              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 = /* starting time in milliseconds */,
            startZoneOffset = ZoneOffset.UTC,
            endTime = sessionStartTime.plus(sessionDuration),
            endZoneOffset = ZoneOffset.UTC,
            exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
            title = "Morning Bike Ride",
            exerciseRoute = exerciseRoute
        )

    healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
}