Ajouter des parcours sportifs

Les parcours sportifs permettent aux utilisateurs de suivre un itinéraire GPS pour les activités physiques associées et de partager des cartes de leurs entraînements avec d'autres applications.

Ce guide décrit comment les applications sont autorisées à écrire des données de parcours dans le cadre d'une session sportive.

Voici un court résumé des fonctionnalités de lecture et d'écriture des parcours sportifs :

  1. Les applications créent une autorisation d'écriture pour les parcours sportifs.
  2. L'insertion se produit en écrivant une session sportive dont le champ est un parcours.
  3. Lecture :
    1. Pour le propriétaire de la session, les données sont accessibles par le biais d'une lecture de session.
    2. À partir d'une application tierce, une boîte de dialogue permet à l'utilisateur d'accorder une lecture unique d'un parcours.

Autorisations

Les parcours sportifs ont leur propre autorisation d'écriture pendant l'exécution (android.permission.health.WRITE_EXERCISE_ROUTE).

Pour ajouter la fonctionnalité de parcours sportifs à votre application, commencez par demander des autorisations d'écriture pour un type de données spécifique.

Demande d'autorisation Android 14

Demande d'autorisation Android 14

Demande d'autorisation Android 13

Demande d'autorisation Android 13

Vous devez également déclarer une autorisation, car chaque parcours est associé à une session sportive (une session = un entraînement).

Voici l'autorisation que vous devez déclarer pour pouvoir écrire des parcours sportifs :

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

Pour lire les parcours sportifs, vous devez demander les autorisations suivantes:

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

Pour demander des autorisations, utilisez la méthode PermissionController.createRequestPermissionResultContract() lorsque vous connectez votre application pour la première fois à Santé Connect. Vous pouvez demander plusieurs autorisations :

  • Lire les données de santé, y compris les données de routage : HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Écrire des données de santé, y compris des données de routage : HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Écrire des données de parcours sportif : HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Lire et écrire des données de parcours

Les applications insèrent un parcours en écrivant une session avec un parcours en tant que champ.

Si l'utilisateur ne dispose pas d'autorisations d'écriture et que le parcours n'est pas défini, celui-ci n'est pas mis à jour.

Si votre application dispose d'une autorisation d'écriture sur le parcours et tente de mettre à jour une session en transmettant un objet de session sans le parcours, le parcours existant est supprimé.

Chaque fois que votre application doit lire des données de parcours fournies par une application tierce, une boîte de dialogue s'affiche pour demander à l'utilisateur d'autoriser l'opération de lecture.

Demander un parcours à partir d'une session

Pour lire une session dans Santé Connect et y demander un parcours :

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.
    }
  }

Écrire un parcours à partir d'une session

Le code suivant montre comment enregistrer une session comprenant un parcours sportif :

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