Thêm tuyến đường tập thể dục

Với tuyến đường tập thể dục, người dùng có thể theo dõi tuyến đường qua GPS cho các hoạt động tập thể dục được liên kết và chia sẻ bản đồ trong bài tập của họ với các ứng dụng khác.

Hướng dẫn này trình bày cách các ứng dụng tiếp nhận quyền ghi dữ liệu về tuyến đường trong phiên tập thể dục.

Dưới đây là nội dung tóm tắt ngắn gọn về chức năng đọc và ghi đối với các tuyến đường tập thể dục:

  1. Các ứng dụng tạo một quyền ghi mới cho các tuyến đường tập thể dục.
  2. Trường hợp chèn xảy ra bằng cách ghi một phiên tập thể dục có một tuyến đường làm trường của phiên đó.
  3. Đọc:
    1. Đối với chủ sở hữu phiên, dữ liệu được truy cập bằng cách dùng một lần đọc phiên.
    2. Từ ứng dụng của bên thứ ba, thông qua một hộp thoại cho phép người dùng cấp quyền đọc một lần đối với tuyến đường.

Quyền

Các tuyến đường tập thể dục có quyền ghi riêng trong thời gian chạy (android.permission.health.WRITE_EXERCISE_ROUTE).

Để thêm chức năng tuyến đường tập thể dục vào ứng dụng của bạn, hãy bắt đầu bằng cách yêu cầu quyền ghi cho một kiểu dữ liệu cụ thể.

Yêu cầu quyền trên Android 14

Yêu cầu quyền trên Android 14

Yêu cầu quyền trên Android 13

Yêu cầu quyền trên Android 13

Bạn cũng phải khai báo quyền đối với bài tập thể dục, vì mỗi tuyến đường được liên kết với một phiên tập thể dục (một phiên = một bài tập).

Dưới đây là quyền bạn cần khai báo để có thể ghi tuyến đường tập thể dục:

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

Để đọc tuyến đường tập thể dục, bạn cần yêu cầu các quyền sau đây:

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

Để yêu cầu cấp quyền, hãy sử dụng phương thức PermissionController.createRequestPermissionResultContract() khi bạn lần đầu kết nối ứng dụng của mình với Health Connect. Dưới đây là một số quyền mà bạn có thể muốn yêu cầu:

  • Đọc dữ liệu sức khoẻ, bao gồm cả dữ liệu tuyến đường: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Ghi dữ liệu sức khoẻ, bao gồm cả dữ liệu tuyến đường: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Ghi dữ liệu tuyến đường tập thể dục: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Đọc và ghi dữ liệu về tuyến đường

Các ứng dụng chèn một tuyến đường bằng cách ghi một phiên có tuyến đường đó làm một trường.

Nếu người dùng không có quyền ghi và tuyến đường chưa được thiết lập, thì tuyến đường này sẽ không cập nhật.

Nếu ứng dụng của bạn có quyền ghi tuyến đường và tìm cách cập nhật một phiên bằng cách truyền đối tượng phiên nhưng không có tuyến đường, thì tuyến đường hiện có sẽ bị xoá.

Bất cứ khi nào ứng dụng cần đọc dữ liệu về tuyến đường do ứng dụng bên thứ ba cung cấp, một hộp thoại sẽ xuất hiện yêu cầu người dùng cho phép thao tác đọc.

Yêu cầu dữ liệu về tuyến đường từ một phiên

Sau đây là cách đọc một phiên trong Health Connect và yêu cầu dữ liệu về tuyến đường từ phiên đó:

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

Ghi một tuyến đường từ một phiên

Mã sau đây minh hoạ cách ghi lại một phiên có dữ liệu về tuyến đường tập thể dục:

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