Adicionar trajetos de exercícios

Os trajetos de exercícios permitem que os usuários acompanhem por GPS o trajeto das atividades físicas associadas e compartilhem mapas dos treinos deles com outros apps.

Este guia descreve como os apps recebem a permissão para gravar dados de trajeto como parte de uma sessão de exercício.

Confira um breve resumo da funcionalidade de leitura e gravação de trajetos de exercícios:

  1. Os apps criam uma nova permissão de gravação para trajetos de exercícios.
  2. A inserção acontece com a criação de uma sessão de exercício com um trajeto como campo.
  3. Leitura:
    1. Para o proprietário da sessão, os dados são acessados usando uma leitura de sessão.
    2. Em um app de terceiros, em uma caixa de diálogo que permite ao usuário conceder uma leitura única de um trajeto.

Permissões

Os trajetos de exercícios têm a própria permissão de gravação no momento de execução (android.permission.health.WRITE_EXERCISE_ROUTE).

Para adicionar a capability de trajeto de exercício ao app, solicite permissões de gravação de um tipo específico de dado.

Solicitação de permissão do Android 14

Solicitação de permissão do Android 14

Solicitação de permissão do Android 13

Solicitação de permissão do Android 13

Você também precisa declarar uma permissão de exercício, já que cada trajeto está associado a uma sessão (o que é igual a um treino).

Confira a permissão necessária para poder gravar trajetos de exercícios:

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

Para ler trajetos de exercícios, você precisa solicitar as seguintes permissões:

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

Para solicitar permissões, use o método PermissionController.createRequestPermissionResultContract() ao conectar seu app ao Conexão Saúde pela primeira vez. Várias permissões que podem ser solicitadas são:

  • Ler dados de integridade, incluindo dados de trajetos: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Gravar dados de saúde, incluindo dados de trajetos: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Gravar dados de trajeto de exercício: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Ler e gravar dados de trajeto

Os apps inserem um trajeto ao gravar uma sessão com um trajeto como campo.

Se o usuário não tiver permissões de gravação e o trajeto não estiver definido, ele não será atualizado.

Se o app tiver uma permissão de gravação de trajeto e tentar atualizar uma sessão transmitindo um objeto de sessão sem um trajeto, o trajeto atual será excluído.

Sempre que seu app precisar ler dados de trajeto fornecidos por um app de terceiros, uma caixa de diálogo aparecerá solicitando a permissão para a operação de leitura.

Solicitar um trajeto em uma sessão

Aprenda a ler uma sessão na Conexão Saúde e solicitar um trajeto nessa sessão:

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

Gravar um trajeto em uma sessão

O código a seguir demonstra como gravar uma sessão que inclui um trajeto de exercício:

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