Aggiungi percorsi per l'esercizio fisico

Questa guida è compatibile con la versione 1.1.0-alpha12 di Connessione Salute.

I percorsi di allenamento consentono agli utenti di monitorare un percorso GPS per le attività di allenamento associate e condividere le mappe dei loro allenamenti con altre app.

Disponibilità della funzionalità

Per determinare se il dispositivo di un utente supporta i percorsi per l'esercizio fisico su Connessione Salute, controlla la disponibilità di FEATURE_PLANNED_EXERCISE sul client:

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
} else {
  // Feature isn't available
}

Per saperne di più, consulta la sezione Verificare la disponibilità delle funzionalità.

Questa guida fornisce informazioni su come richiedere le autorizzazioni all'utente e descrive anche come le app ricevono l'autorizzazione a scrivere dati di itinerario nell'ambito di una sessione di allenamento.

La funzionalità di lettura e scrittura per i percorsi di allenamento include:

  1. Le app creano una nuova autorizzazione di scrittura per i percorsi di allenamento.
  2. L'inserimento avviene scrivendo una sessione di allenamento con un percorso come campo.
  3. Lettura:
    1. Per il proprietario della sessione, si accede ai dati utilizzando 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.

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

Se la tua app dispone dell'autorizzazione di scrittura delle route e tenta di aggiornare una sessione passando un oggetto sessione senza una route, la route esistente viene eliminata.

Autorizzazioni richieste

L'accesso al percorso dell'allenamento è protetto dalle seguenti autorizzazioni:

  • android.permission.health.READ_EXERCISE_ROUTE
  • android.permission.health.WRITE_EXERCISE_ROUTE

Per aggiungere la funzionalità di percorso dell'allenamento alla tua app, inizia richiedendo le autorizzazioni di scrittura per il tipo di dati ExerciseSession.

Ecco l'autorizzazione che devi dichiarare per poter scrivere un percorso di allenamento:

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

Per leggere il percorso dell'allenamento, devi richiedere le seguenti autorizzazioni:

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

Devi anche dichiarare un'autorizzazione di allenamento, poiché ogni percorso è associato a una sessione di allenamento (una sessione = un allenamento).

Per richiedere le autorizzazioni, utilizza il metodo PermissionController.createRequestPermissionResultContract() quando connetti per la prima volta la tua app a Connessione Salute. Alcune autorizzazioni che potresti voler richiedere sono:

  • Leggi i dati sanitari, inclusi i dati sul percorso: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Scrivi dati sanitari, inclusi i dati del percorso: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Scrittura dei dati del percorso per l'esercizio fisico: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Richiedere le autorizzazioni all'utente

Dopo aver creato un'istanza client, l'app deve richiedere le autorizzazioni all'utente. Gli utenti devono poter concedere o negare le autorizzazioni in qualsiasi momento.

A questo scopo, crea un insieme di autorizzazioni per i tipi di dati richiesti. Assicurati che le autorizzazioni nel set siano dichiarate prima nel file manifest di Android.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(ExerciseSessionRecord::class),
  HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)

Utilizza getGrantedPermissions per verificare se alla tua app sono già state concesse le autorizzazioni richieste. In caso contrario, utilizza createRequestPermissionResultContract per richiedere queste autorizzazioni. Viene visualizzata la schermata delle autorizzazioni di Connessione Salute.

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

Poiché gli utenti possono concedere o revocare le autorizzazioni in qualsiasi momento, la tua app deve controllare periodicamente le autorizzazioni concesse e gestire gli scenari in cui l'autorizzazione viene persa.

Informazioni incluse in un record di sessione di allenamento

Ogni record di sessione di allenamento contiene le seguenti informazioni:

  • Il tipo di allenamento, ad esempio ciclismo.
  • L'itinerario dell'esercizio, che contiene informazioni come latitudine, longitudine e altitudine.

Aggregazioni supportate

Non sono presenti aggregazioni supportate per questo tipo di dati.

Esempio di utilizzo

Richiedi un percorso o scrivine uno da una sessione.

Richiedere un percorso da una sessione

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

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

Scrivere un percorso da una sessione

Il seguente codice mostra come registrare una sessione che include un percorso di allenamento:

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