Tambahkan rute latihan

Panduan ini kompatibel dengan Health Connect versi 1.1.0-alpha12.

Rute olahraga memungkinkan pengguna melacak rute GPS untuk aktivitas olahraga terkait dan membagikan peta olahraga mereka ke aplikasi lain.

Panduan ini memberikan informasi tentang cara meminta izin dari pengguna dan juga menguraikan cara aplikasi menerima izin untuk menulis data rute sebagai bagian dari sesi olahraga.

Berikut adalah ringkasan singkat fungsi baca dan tulis untuk rute olahraga:

  1. Aplikasi membuat izin tulis baru untuk rute olahraga.
  2. Penyisipan dilakukan dengan menulis sesi olahraga beserta rute sebagai kolomnya.
  3. Membaca:
    1. Untuk pemilik sesi, data diakses menggunakan pembacaan sesi.
    2. Dari aplikasi pihak ketiga, melalui dialog yang memungkinkan pengguna memberikan pembacaan rute satu kali.

Meminta izin dari pengguna

Setelah membuat instance klien, aplikasi Anda perlu meminta izin dari pengguna. Pengguna harus diizinkan untuk memberikan atau menolak izin setiap saat.

Untuk melakukannya, buat kumpulan izin untuk jenis data yang diperlukan. Pastikan izin dalam kumpulan dideklarasikan dalam manifes Android Anda terlebih dahulu.

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

Gunakan getGrantedPermissions untuk mengetahui apakah aplikasi Anda sudah mendapatkan izin yang diperlukan. Jika belum, gunakan createRequestPermissionResultContract untuk meminta izin tersebut. Tindakan ini akan menampilkan layar izin Health Connect.

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

Karena pengguna dapat memberikan atau mencabut izin kapan saja, aplikasi Anda harus memeriksa izin yang diberikan secara berkala dan menangani skenario saat izin tersebut hilang.

Izin baca dan tulis rute olahraga

Rute olahraga memiliki izin tulis runtime-nya sendiri (android.permission.health.WRITE_EXERCISE_ROUTE).

Untuk menambahkan kemampuan rute olahraga ke aplikasi Anda, mulailah dengan meminta izin tulis untuk jenis data tertentu.

Anda juga harus mendeklarasikan izin olahraga, karena setiap rute dikaitkan dengan sesi olahraga (satu sesi = satu olahraga).

Berikut adalah izin yang harus Anda deklarasikan agar dapat menulis rute olahraga:

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

Untuk membaca rute olahraga, Anda perlu meminta izin berikut:

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

Untuk meminta izin, gunakan metode PermissionController.createRequestPermissionResultContract() saat Anda pertama kali menghubungkan aplikasi ke Health Connect. Beberapa izin yang mungkin ingin Anda minta adalah:

  • Membaca data kesehatan, termasuk data rute: HealthPermission.getReadPermission(ExerciseSessionRecord::class)
  • Menulis data kesehatan, termasuk data rute: HealthPermission.getWritePermission(ExerciseSessionRecord::class)
  • Menulis data rute olahraga: HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE

Membaca dan menulis data rute

Aplikasi menyisipkan rute dengan menulis sesi dengan rute sebagai kolom.

Jika pengguna tidak memiliki izin tulis dan rute tidak ditetapkan, rute tidak akan diperbarui.

Jika aplikasi Anda memiliki izin tulis rute dan mencoba memperbarui sesi dengan meneruskan objek sesi tanpa rute, rute yang sudah ada akan dihapus.

Setiap kali aplikasi Anda perlu membaca data rute yang disediakan oleh aplikasi pihak ketiga, dialog akan muncul untuk meminta pengguna mengizinkan operasi baca.

Meminta rute dari sesi

Berikut cara membaca sesi di Health Connect dan meminta rute dari sesi tersebut:

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

Menulis rute dari sesi

Kode berikut menunjukkan cara merekam sesi yang menyertakan rute olahraga:

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