Добавьте маршруты тренировок

Маршруты тренировок позволяют пользователям отслеживать GPS-маршруты соответствующих тренировок и делиться картами своих тренировок с другими приложениями.

В этом руководстве описывается, как приложения получают разрешение на запись данных маршрута в рамках сеанса тренировки.

Вот краткое описание функций чтения и записи для маршрутов упражнений:

  1. Приложения создают новое разрешение на запись для маршрутов тренировок.
  2. Вставка происходит путем записи сеанса тренировки с маршрутом в качестве поля.
  3. Чтение:
    1. Для владельца сеанса доступ к данным осуществляется посредством чтения сеанса.
    2. Из стороннего приложения через диалоговое окно, позволяющее пользователю разрешить однократное чтение маршрута.

Разрешения

Маршруты упражнений имеют собственное разрешение на запись во время выполнения ( android.permission.health.WRITE_EXERCISE_ROUTE ).

Чтобы добавить возможность маршрута тренировки в свое приложение, начните с запроса разрешений на запись для определенного типа данных.

Запрос разрешения Android 14

Запрос разрешения Android 14

Запрос разрешения Android 13

Запрос разрешения Android 13

Вам также необходимо задекларировать разрешение на тренировку, поскольку каждый маршрут связан с тренировкой (один сеанс = одна тренировка).

Вот разрешение, которое вам нужно объявить, чтобы иметь возможность писать маршруты упражнений:

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

Чтобы прочитать маршруты тренировок, вам необходимо запросить следующие разрешения:

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

Чтобы запросить разрешения, используйте метод PermissionController.createRequestPermissionResultContract() при первом подключении приложения к Health Connect. Несколько разрешений, которые вы можете запросить:

  • Чтение данных о работоспособности, включая данные маршрута: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Запись данных о работоспособности, включая данные маршрута: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Запишите данные маршрута тренировки: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE .

Чтение и запись данных маршрута

Приложения вставляют маршрут, записывая сеанс с маршрутом в качестве поля.

Если у пользователя нет разрешений на запись и маршрут не установлен, маршрут не обновляется.

Если ваше приложение имеет разрешение на запись маршрута и пытается обновить сеанс, передав объект сеанса без маршрута, существующий маршрут удаляется.

Всякий раз, когда вашему приложению необходимо прочитать данные маршрута, предоставленные сторонним приложением, появляется диалоговое окно с просьбой разрешить операцию чтения.

Запросить маршрут из сеанса

Вот как прочитать сеанс в Health Connect и запросить маршрут из этого сеанса:

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

Написать маршрут из сеанса

Следующий код демонстрирует, как записать сеанс, включающий маршрут тренировки:

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