Panduan ini kompatibel dengan Health Connect versi 1.1.0-alpha11.
Health Connect menyediakan jenis data olahraga terencana untuk memungkinkan aplikasi pelatihan menulis rencana pelatihan dan memungkinkan aplikasi olahraga membaca rencana pelatihan. Olahraga yang direkam (olahraga) dapat dibaca kembali untuk analisis performa yang dipersonalisasi guna membantu pengguna mencapai sasaran pelatihan mereka.
Ketersediaan fitur
Untuk menentukan apakah perangkat pengguna mendukung rencana latihan di Health Connect,
periksa ketersediaan FEATURE_PLANNED_EXERCISE
di klien:
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Feature is available
} else {
// Feature isn't available
}
Lihat Memeriksa ketersediaan fitur untuk mempelajari lebih lanjut.
Izin yang diperlukan
Akses ke rencana pelatihan dilindungi oleh izin berikut:
android.permission.health.READ_PLANNED_EXERCISE
android.permission.health.WRITE_PLANNED_EXERCISE
Deklarasikan izin ini di Konsol Play untuk aplikasi Anda, serta dalam manifes aplikasi:
<application>
<uses-permission
android:name="android.permission.health.READ_PLANNED_EXERCISE" />
<uses-permission
android:name="android.permission.health.WRITE_PLANNED_EXERCISE" />
...
</application>
Anda bertanggung jawab untuk mendeklarasikan semua izin yang sesuai yang ingin Anda gunakan di perangkat dan aplikasi Anda. Anda juga harus memeriksa apakah setiap izin telah diberikan oleh pengguna sebelum digunakan.
Izin terkait
Program latihan ditautkan ke sesi olahraga. Oleh karena itu, pengguna harus memberikan izin untuk menggunakan setiap jenis data yang terkait dengan rencana pelatihan agar dapat menggunakan fitur Health Connect ini sepenuhnya.
Misalnya, jika rencana pelatihan mengukur detak jantung pengguna selama serangkaian lari, izin berikut mungkin perlu dideklarasikan oleh developer dan diberikan oleh pengguna untuk menulis sesi olahraga dan membaca hasilnya untuk evaluasi di lain waktu:
android.permission.health.READ_EXERCISE
android.permission.health.READ_EXERCISE_ROUTE
android.permission.health.READ_HEART_RATE
android.permission.health.WRITE_EXERCISE
android.permission.health.WRITE_EXERCISE_ROUTE
android.permission.health.WRITE_HEART_RATE
Namun, sering kali aplikasi yang membuat rencana latihan dan mengevaluasi performa terhadap rencana tidak sama dengan aplikasi yang menggunakan rencana latihan dan menulis data olahraga yang sebenarnya. Bergantung pada jenis aplikasi, tidak semua izin baca dan tulis akan diperlukan. Misalnya, Anda mungkin hanya memerlukan izin ini untuk setiap jenis aplikasi:
Aplikasi program latihan | Aplikasi olahraga |
---|---|
WRITE_PLANNED_EXERCISE |
READ_PLANNED_EXERCISE |
READ_EXERCISE |
WRITE_EXERCISE |
READ_EXERCISE_ROUTE |
WRITE_EXERCISE_ROUTE |
READ_HEART_RATE |
WRITE_HEART_RATE |
Informasi yang disertakan dalam data sesi olahraga terencana
- Judul sesi.
- Daftar blok latihan yang direncanakan.
- Waktu mulai dan berakhir sesi.
- Jenis latihan.
- Catatan untuk aktivitas.
- Metadata.
- ID sesi olahraga yang telah selesai — ID ini ditulis secara otomatis setelah sesi olahraga yang terkait dengan sesi olahraga yang direncanakan ini selesai.
Informasi yang disertakan dalam data blok latihan terencana
Blok olahraga yang direncanakan berisi daftar langkah olahraga, untuk mendukung pengulangan berbagai kelompok langkah (misalnya, lakukan urutan curl lengan, burpee, dan sit-up lima kali berturut-turut).
- Deskripsi blok.
- Daftar langkah latihan yang direncanakan.
- Jumlah pengulangan.
Informasi yang disertakan dalam data langkah latihan terencana
- Deskripsi langkah.
- Kategori olahraga.
- Jenis olahraga.
- Daftar sasaran performa.
- Sasaran penyelesaian.
Agregasi yang didukung
Tidak ada agregasi yang didukung untuk jenis data ini.
Contoh penggunaan
Misalnya, pengguna merencanakan lari selama 90 menit dua hari dari sekarang. Lari ini akan menampilkan tiga putaran di sekitar danau dengan target detak jantung antara 90 dan 110 bpm.
- Sesi latihan terencana dengan hal berikut ditentukan oleh pengguna di
aplikasi rencana latihan:
- Awal dan akhir lari yang direncanakan
- Jenis olahraga (lari)
- Jumlah putaran (pengulangan)
- Target performa untuk detak jantung (antara 90 dan 110 bpm)
- Informasi ini dikelompokkan ke dalam blok dan langkah olahraga, serta ditulis
ke Health Connect oleh aplikasi rencana pelatihan sebagai
PlannedExerciseSessionRecord
. - Pengguna melakukan sesi yang direncanakan (berjalan).
- Data olahraga yang terkait dengan sesi dicatat:
- Oleh perangkat wearable selama sesi berlangsung. Misalnya, detak jantung.
Data ini ditulis ke Health Connect sebagai jenis data untuk
aktivitas. Dalam hal ini,
HeartRateRecord
. - Secara manual oleh pengguna setelah sesi. Misalnya, menunjukkan
awal dan akhir operasi yang sebenarnya. Data ini ditulis ke Health
Connect sebagai
ExerciseSessionRecord
.
- Oleh perangkat wearable selama sesi berlangsung. Misalnya, detak jantung.
Data ini ditulis ke Health Connect sebagai jenis data untuk
aktivitas. Dalam hal ini,
- Pada lain waktu, aplikasi rencana pelatihan akan membaca data dari Health Connect untuk mengevaluasi performa sebenarnya terhadap target yang ditetapkan oleh pengguna dalam sesi olahraga yang direncanakan.
Merencanakan latihan dan menetapkan target
Pengguna dapat merencanakan olahraga mereka di masa mendatang dan menetapkan target. Tulis ini ke Health Connect sebagai sesi olahraga terencana.
Dalam contoh yang dijelaskan di Contoh penggunaan, pengguna merencanakan lari selama 90 menit dua hari dari sekarang. Lari ini akan menampilkan tiga putaran di sekitar danau dengan target detak jantung antara 90 dan 110 bpm.
Cuplikan seperti ini dapat ditemukan di pengendali formulir untuk aplikasi yang mencatat sesi olahraga terencana ke Health Connect. Data ini juga dapat ditemukan di titik transfer untuk integrasi, misalnya dengan layanan yang menawarkan pelatihan.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class))) {
// The user hasn't granted the app permission to write planned exercise session data.
return
}
val plannedDuration = Duration.ofMinutes(90)
val plannedStartDate = LocalDate.now().plusDays(2)
val plannedExerciseSessionRecord = PlannedExerciseSessionRecord(
startDate = plannedStartDate,
duration = plannedDuration,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
blocks = listOf(
PlannedExerciseBlock(
repetitions = 1, steps = listOf(
PlannedExerciseStep(
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
exercisePhase = PlannedExerciseStep.EXERCISE_PHASE_ACTIVE,
completionGoal = ExerciseCompletionGoal.RepetitionsGoal(repetitions = 3),
performanceTargets = listOf(
ExercisePerformanceTarget.HeartRateTarget(
minHeartRate = 90.0, maxHeartRate = 110.0
)
)
),
), description = "Three laps around the lake"
)
),
title = "Run at lake",
notes = null
)
val insertedPlannedExerciseSessions =
healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()
Mencatat data olahraga dan aktivitas
Dua hari kemudian, pengguna mencatat sesi olahraga yang sebenarnya. Tulis ini ke Health Connect sebagai sesi latihan.
Dalam contoh ini, durasi sesi pengguna sama persis dengan durasi yang direncanakan.
Cuplikan berikut dapat ditemukan di pengendali formulir untuk aplikasi yang mencatat sesi olahraga ke Health Connect. Data ini juga dapat ditemukan di pengendali impor dan ekspor data untuk perangkat wearable yang dapat mendeteksi dan mencatat sesi latihan.
insertedPlannedExerciseSessionId
di sini digunakan kembali dari contoh sebelumnya. Dalam
aplikasi sebenarnya, ID akan ditentukan oleh pengguna yang memilih sesi olahraga
yang direncanakan dari daftar sesi yang ada.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't granted the app permission to write exercise session data.
return
}
val sessionDuration = Duration.ofMinutes(90)
val sessionEndTime = Instant.now()
val sessionStartTime = sessionEndTime.minus(sessionDuration)
val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
segments = listOf(
ExerciseSegment(
startTime = sessionStartTime,
endTime = sessionEndTime,
repetitions = 3,
segmentType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING
)
),
title = "Run at lake",
plannedExerciseSessionId = insertedPlannedExerciseSessionId,
)
val insertedExerciseSessions =
healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
Perangkat wearable juga mencatat detak jantung mereka selama berlari. Cuplikan berikut dapat digunakan untuk membuat data dalam rentang target.
Dalam aplikasi sebenarnya, bagian utama cuplikan ini mungkin ditemukan di pengendali untuk pesan dari perangkat wearable, yang akan menulis pengukuran ke Health Connect setelah pengumpulan.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(HeartRateRecord::class))) {
// The user doesn't granted the app permission to write heart rate record data.
return
}
val samples = mutableListOf<HeartRateRecord.Sample>()
var currentTime = sessionStartTime
while (currentTime.isBefore(sessionEndTime)) {
val bpm = Random.nextInt(21) + 90
val heartRateRecord = HeartRateRecord.Sample(
time = currentTime,
beatsPerMinute = bpm.toLong(),
)
samples.add(heartRateRecord)
currentTime = currentTime.plusSeconds(180)
}
val heartRateRecord = HeartRateRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
samples = samples,
)
val insertedHeartRateRecords = healthConnectClient.insertRecords(listOf(heartRateRecord))
Mengevaluasi target performa
Sehari setelah olahraga pengguna, Anda dapat mengambil olahraga yang dicatat, memeriksa target olahraga yang direncanakan, dan mengevaluasi jenis data tambahan untuk menentukan apakah target yang ditetapkan tercapai.
Cuplikan seperti ini kemungkinan akan ditemukan dalam tugas berkala untuk mengevaluasi target performa atau saat memuat daftar latihan dan menampilkan notifikasi tentang target performa di aplikasi.
// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.containsAll(
listOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class)
)
)
) {
// The user doesn't granted the app permission to read exercise session record data.
return
}
val searchDuration = Duration.ofDays(1)
val searchEndTime = Instant.now()
val searchStartTime = searchEndTime.minus(searchDuration)
val response = healthConnectClient.readRecords(
ReadRecordsRequest<ExerciseSessionRecord>(
timeRangeFilter = TimeRangeFilter.between(searchStartTime, searchEndTime)
)
)
for (exerciseRecord in response.records) {
val plannedExerciseRecordId = exerciseRecord.plannedExerciseSessionId
val plannedExerciseRecord =
if (plannedExerciseRecordId == null) null else healthConnectClient.readRecord(
PlannedExerciseSessionRecord::class, plannedExerciseRecordId
).record
if (plannedExerciseRecord != null) {
val aggregateRequest = AggregateRequest(
metrics = setOf(HeartRateRecord.BPM_AVG),
timeRangeFilter = TimeRangeFilter.between(
exerciseRecord.startTime, exerciseRecord.endTime
),
)
val aggregationResult = healthConnectClient.aggregate(aggregateRequest)
val maxBpm = aggregationResult[HeartRateRecord.BPM_MAX]
val minBpm = aggregationResult[HeartRateRecord.BPM_MIN]
if (maxBpm != null && minBpm != null) {
plannedExerciseRecord.blocks.forEach { block ->
block.steps.forEach { step ->
step.performanceTargets.forEach { target ->
when (target) {
is ExercisePerformanceTarget.HeartRateTarget -> {
val minTarget = target.minHeartRate
val maxTarget = target.maxHeartRate
if(
minBpm >= minTarget && maxBpm <= maxTarget
) {
// Success!
}
}
// Handle more target types
}
}
}
}
}
}
}
}