Aggiungi percorsi per l'esercizio fisico

I percorsi per l'esercizio fisico consentono agli utenti di rilevare un percorso GPS per l'allenamento associato attività fisica e condividere mappe dei loro allenamenti con altre app.

Questa guida illustra in che modo le app ricevono l'autorizzazione a scrivere dati sui percorsi nell'ambito di: una sessione di allenamento.

Ecco un breve riepilogo della funzionalità di lettura e scrittura per i percorsi degli allenamenti:

  1. Le app creano una nuova autorizzazione di scrittura per i percorsi degli allenamenti.
  2. L'inserimento avviene scrivendo una sessione di allenamento con un percorso come campo.
  3. Lettura:
    1. Per il proprietario della sessione, l'accesso ai dati avviene mediante una lettura della sessione.
    2. Da un'app di terze parti, tramite una finestra di dialogo che consente all'utente di concedere una lettura una tantum di un percorso.

Autorizzazioni

Le route di allenamento hanno la propria autorizzazione di scrittura di runtime (android.permission.health.WRITE_EXERCISE_ROUTE)

Per aggiungere la funzionalità dei percorsi per l'esercizio fisico alla tua app, inizia richiedendo di scrittura autorizzazioni per un tipo di dati specifico.

Richiesta di autorizzazione per Android 14

Richiesta di autorizzazione per Android 14

Richiesta di autorizzazione per Android 13

Richiesta di autorizzazione per Android 13

Devi anche dichiarare un'autorizzazione di allenamento, in quanto ogni percorso è associato con una sessione di allenamento (una sessione = un esercizio).

Ecco l'autorizzazione che devi dichiarare per poter scrivere percorsi per gli allenamenti:

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

Per leggere i percorsi per gli allenamenti, devi richiedere le seguenti autorizzazioni:

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

Per richiedere le autorizzazioni, utilizza PermissionController.createRequestPermissionResultContract() quando per prima cosa connetti la tua app a Connessione Salute. Alcune autorizzazioni che vuoi richiedere sono:

  • Lettura dei dati sanitari, compresi i dati sui percorsi: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Scrivi dati sanitari, compresi i dati sui percorsi: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Scrittura dei dati del percorso per l'esercizio fisico: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE
di Gemini Advanced.

Leggere e scrivere i dati dei percorsi

Le app inseriscono un percorso scrivendo una sessione con una route come campo.

Se l'utente non dispone delle autorizzazioni di scrittura e la route non è impostata, viene non si aggiorna.

Se la tua app dispone dell'autorizzazione di scrittura del percorso e prova ad aggiornare una sessione in un oggetto sessione senza route, la route esistente viene eliminata.

Ogni volta che l'app deve leggere i dati del percorso forniti da un'app di terze parti, viene viene visualizzata una finestra di dialogo che chiede all'utente di consentire l'operazione di lettura.

Richiedere un percorso da una sessione

Ecco come leggere una sessione in Connessione Salute e richiedere un percorso sessione:

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

Scrivere un percorso da una sessione

Il seguente codice mostra come registrare una sessione che include un percorso per l'esercizio fisico:

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