Jika ingin membuat pengalaman latihan fisik di aplikasi, Anda dapat menggunakan Health Connect untuk melakukan hal-hal seperti:
- Menulis sesi latihan
- Menulis rute latihan
- Menulis metrik latihan fisik seperti detak jantung, kecepatan, dan jarak
- Membaca data latihan fisik dari aplikasi lain
Panduan ini menjelaskan cara membuat fitur latihan fisik ini, yang mencakup jenis data, eksekusi di latar belakang, izin, alur kerja yang direkomendasikan, dan praktik terbaik.
Ringkasan: Membangun Pelacak Latihan Fisik yang Komprehensif
Anda dapat membangun pengalaman pelacakan latihan fisik yang komprehensif menggunakan Health Connect dengan mengikuti langkah-langkah inti berikut:
- Menerapkan izin dengan benar berdasarkan Izin Kesehatan.
- Merekam sesi menggunakan
ExerciseSessionRecord. - Menulis data latihan secara konsisten selama sesi.
- Mengelola eksekusi latar belakang dengan benar untuk memverifikasi pengambilan data berkelanjutan.
- Membaca data sesi latihan fisik untuk ringkasan dan analisis pasca latihan fisik.
Alur kerja ini memungkinkan interoperabilitas dengan aplikasi Health Connect lainnya dan memverifikasi akses data yang dikontrol pengguna.
Sebelum memulai
Sebelum menerapkan fitur latihan:
- Integrasikan Health Connect menggunakan dependensi yang sesuai.
- Buat instance
HealthConnectClient. - Verifikasi bahwa aplikasi Anda menerapkan alur izin runtime berdasarkan Izin Kesehatan.
- Jika alur kerja Anda menggunakan GPS, siapkan izin lokasi dan layanan latar depan.
Konsep utama
Health Connect merepresentasikan data latihan fisik menggunakan beberapa komponen inti.
ExerciseSessionRecord berfungsi sebagai catatan pusat untuk latihan fisik,
yang berisi detail seperti waktu mulai atau berakhir dan jenis latihan. Selama sesi, berbagai jenis data seperti HeartRateRecord atau SpeedRecord dapat direkam. Untuk aktivitas luar ruangan, ExerciseRoute menyimpan data GPS, yang ditautkan ke sesi yang sesuai.
Sesi olahraga
ExerciseSessionRecord adalah catatan pusat untuk data latihan fisik, yang merepresentasikan
satu sesi latihan fisik. Setiap data menyimpan:
startTimeendTimeexerciseType- Metadata sesi opsional (judul, catatan)
ExerciseSessionRecord juga dapat berisi rute latihan, putaran, dan
segmen sebagai bagian dari datanya. Selain itu, jenis data lain seperti
HeartRateRecord atau SpeedRecord dapat direkam selama sesi dan
dikaitkan dengannya.
Jenis data terkait
Data yang terkait dengan sesi latihan diwakili oleh jenis rekaman individu. Jenis umum mencakup:
HeartRateRecord: Mewakili serangkaian pengukuran detak jantung.SpeedRecord: Mewakili serangkaian pengukuran kecepatan.DistanceRecord: Mewakili jarak yang ditempuh di antara pembacaan.TotalCaloriesBurnedRecord: Menampilkan total kalori yang terbakar di antara pembacaan.ElevationGainedRecord: Menunjukkan elevasi yang diperoleh di antara pembacaan.StepsCadenceRecord: Mewakili ritme langkah di antara pembacaan.PowerRecord: Menampilkan output daya di antara pembacaan, umum dalam aktivitas seperti bersepeda.
Untuk mengetahui daftar lengkap jenis data, lihat Jenis data Health Connect.
Rute olahraga
Anda dapat mengaitkan rute dengan latihan fisik di luar ruangan menggunakan ExerciseRoute. Rute
terdiri dari objek ExerciseRoute.Location berurutan yang masing-masing berisi:
- Lintang dan bujur
- Ketinggian opsional
- Bearing opsional
- Informasi akurasi
- Stempel waktu
Rute sesi link
ExerciseRoute berisi data lokasi berurutan untuk sesi latihan. Data ini tidak diperlakukan sebagai catatan independen di Health Connect. Sebagai gantinya,
Anda memberikan data ExerciseRoute saat menyisipkan atau memperbarui
ExerciseSessionRecord.
Pertimbangan pengembangan
Aplikasi pelacakan latihan fisik sering kali perlu berjalan dalam jangka waktu yang lama, sering kali di latar belakang saat layar nonaktif. Saat membuat fitur latihan fisik, penting untuk mempertimbangkan cara mengelola eksekusi di latar belakang dan meminta izin yang diperlukan untuk data latihan fisik.
Eksekusi latar belakang
Aplikasi latihan fisik biasanya berjalan dengan layar nonaktif. Saat dalam status ini, Anda harus menggunakan:
- Layanan latar depan untuk pengambilan sampel lokasi dan sensor
WorkManageruntuk penulisan atau sinkronisasi yang ditangguhkan- Strategi pengelompokan untuk penulisan data reguler
Pertahankan kontinuitas dengan menjaga konsistensi ID sesi di semua penulisan.
Izin
Aplikasi Anda harus meminta izin Health Connect yang relevan sebelum membaca atau menulis data latihan fisik. Izin umum untuk latihan fisik mencakup sesi latihan, rute latihan, dan metrik seperti detak jantung atau kecepatan. Hal tersebut meliputi:
- Sesi latihan: Izin baca dan tulis untuk
ExerciseSessionRecord. - Rute latihan: Izin baca dan tulis untuk
ExerciseRoute. - Detak jantung: Izin baca dan tulis untuk
HeartRateRecord. - Kecepatan: Izin baca dan tulis untuk
SpeedRecord. - Jarak: Izin baca dan tulis untuk
DistanceRecord. - Kalori: Izin baca dan tulis untuk
TotalCaloriesBurnedRecord. - Peningkatan Hak Istimewa: Izin baca dan tulis untuk
ElevationGainedRecord. - Ritme Langkah: Izin baca dan tulis untuk
StepsCadenceRecord. - Power: Izin baca dan tulis untuk
PowerRecord. - Langkah-langkah: Izin baca dan tulis untuk
StepsRecord.
Berikut contoh cara meminta beberapa izin untuk sesi latihan fisik yang mencakup data rute, detak jantung, jarak, kalori, kecepatan, dan langkah:
Setelah membuat instance klien, aplikasi Anda perlu meminta izin dari pengguna. Pengguna harus diizinkan untuk memberikan atau menolak izin kapan saja.
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),
HealthPermission.getReadPermission(ExerciseRoute::class),
HealthPermission.getWritePermission(ExerciseRoute::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(SpeedRecord::class),
HealthPermission.getWritePermission(SpeedRecord::class),
HealthPermission.getReadPermission(DistanceRecord::class),
HealthPermission.getWritePermission(DistanceRecord::class),
HealthPermission.getReadPermission(TotalCaloriesBurnedRecord::class),
HealthPermission.getWritePermission(TotalCaloriesBurnedRecord::class),
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::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 perlu memeriksa izin setiap kali sebelum menggunakannya dan menangani skenario saat izin hilang.
Untuk meminta izin, panggil fungsi checkPermissionsAndRun:
if (!granted.containsAll(PERMISSIONS)) {
requestPermissions.launch(PERMISSIONS)
// Check if required permissions are not granted, and return
}
// Permissions already granted; proceed with inserting or reading data
Jika Anda hanya perlu meminta izin untuk satu jenis data, seperti detak jantung, sertakan hanya jenis data tersebut dalam set izin Anda:
Akses ke detak jantung dilindungi oleh izin berikut:
android.permission.health.READ_HEART_RATEandroid.permission.health.WRITE_HEART_RATE
Untuk menambahkan kemampuan detak jantung ke aplikasi Anda, mulailah dengan meminta
izin untuk jenis data HeartRateRecord.
Berikut adalah izin yang harus Anda deklarasikan agar dapat menulis data detak jantung:
<application>
<uses-permission
android:name="android.permission.health.WRITE_HEART_RATE" />
...
</application>
Untuk membaca detak jantung, Anda perlu meminta izin berikut:
<application>
<uses-permission
android:name="android.permission.health.READ_HEART_RATE" />
...
</application>
Menerapkan sesi latihan fisik
Bagian ini menjelaskan alur kerja yang direkomendasikan untuk merekam data latihan fisik.
Mulai sesi
Untuk membuat latihan fisik baru:
- Buat ID sesi unik: Pastikan ID ini stabil. Jika proses aplikasi Anda dihentikan dan dimulai ulang, Anda harus dapat melanjutkan penggunaan ID yang sama untuk mencegah sesi yang terfragmentasi.
- Tetapkan
metadata.clientRecordIduntuk mencegah duplikat selama percobaan ulang sinkronisasi. - Menulis
ExerciseSessionRecord: Sertakan waktu mulai. - Mulai mengumpulkan data Jenis data dan GPS: Hanya mulai mengumpulkan data ini setelah rekaman sesi berhasil diinisialisasi.
Contoh:
val sessionId = UUID.randomUUID().toString()
val sessionClientId = UUID.randomUUID().toString()
val session = ExerciseSessionRecord(
id = sessionId,
exerciseType = ExerciseType.EXERCISE_TYPE_RUNNING,
startTime = Instant.now(),
endTime = null,
metadata = Metadata(clientRecordId = sessionClientId),
)
healthConnectClient.insertRecords(listOf(session))
Mencatat rute latihan
Untuk mempelajari lebih lanjut panduan membaca, lihat Membaca data mentah.
Saat merekam rute latihan, Anda harus mengelompokkan data. Artinya, alih-alih menyimpan setiap titik GPS saat terjadi, Anda mengumpulkan sekelompok titik dan menyimpannya sekaligus dalam satu panggilan.
Hal ini penting karena setiap kali aplikasi Anda membaca atau menulis ke Health Connect, aplikasi tersebut menggunakan sedikit daya baterai dan daya pemrosesan.
Kode berikut menunjukkan cara merekam dalam batch:
// 1. Create a list to hold your route locations
val routeLocations = mutableListOf<ExerciseRoute.Location>()
// 2. Add points to your list as the exercise happens
routeLocations.add(
ExerciseRoute.Location(
time = Instant.now(),
latitude = 37.7749,
longitude = -122.4194
)
)
// ... keep adding points over a period of time ...
// 3. Save the whole list at once (Batching)
val session = ExerciseSessionRecord(
startTime = startTime,
endTime = endTime,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
// We pass the whole list here
exerciseRoute = ExerciseRoute(routeLocations)
)
healthConnectClient.insertRecords(listOf(session))
Mengakhiri sesi
Setelah menghentikan pengumpulan data:
- Memperbarui data: Aplikasi Anda memperbarui
ExerciseSessionRecorddenganendTime. - Selesaikan data: Secara opsional, hitung nilai ringkasan (seperti total jarak atau kecepatan rata-rata) dan tulis sebagai catatan tambahan.
val finishedSession = session.copy(endTime = Instant.now())
healthConnectClient.updateRecords(listOf(finishedSession))
Membaca data latihan fisik
Aplikasi dapat membaca sesi latihan dan data terkaitnya untuk meringkas aktivitas,
memberikan insight kesehatan, atau menyinkronkan data dengan server eksternal. Misalnya, Anda dapat membaca ExerciseSessionRecord, lalu membuat kueri HeartRateRecord atau DistanceRecord yang terjadi selama interval waktu yang sama.
Jika Anda perlu menyinkronkan data latihan fisik dengan server backend, atau menjaga datastore aplikasi Anda tetap terbaru dengan Health Connect, gunakan ChangeLogs. Dengan demikian, Anda dapat mengambil daftar data yang disisipkan, diperbarui, atau dihapus sejak waktu tertentu, yang lebih efisien daripada melacak perubahan secara manual atau berulang kali membaca semua data. Untuk mengetahui informasi selengkapnya, lihat Menyinkronkan data dengan Health Connect.
Membaca sesi
Untuk membaca sesi latihan, gunakan ReadRecordsRequest dengan
ExerciseSessionRecord sebagai jenisnya. Anda biasanya memfilter ini menurut rentang waktu
tertentu.
suspend fun readExerciseSessions(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = ExerciseSessionRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (exerciseRecord in response.records) {
// Process each session
val exerciseType = exerciseRecord.exerciseType
val notes = exerciseRecord.notes
}
}
Membaca rute
Meskipun data ExerciseRoute ditulis sebagai bagian dari sesi latihan, data tersebut harus dibaca secara terpisah. Gunakan metode getExerciseRoute() dengan ID
sesi untuk membaca data rutenya:
suspend fun readExerciseRoute(
healthConnectClient: HealthConnectClient,
exerciseSessionRecord: ExerciseSessionRecord
) {
// Check if the session has a route
val route = healthConnectClient.getExerciseRoute(
exerciseSessionRecordId = exerciseSessionRecord.metadata.id
)
when (route) {
is ExerciseRouteResponse.Success -> {
val locations = route.exerciseRoute.locations
for (location in locations) {
// Use latitude, longitude, and altitude
}
}
is ExerciseRouteResponse.NoData -> {
// Handle case where no route exists
}
is ExerciseRouteResponse.ConsentRequired -> {
// Handle case where permissions are missing
}
}
}
Jenis data baca
Untuk membaca data terperinci tertentu (seperti detak jantung) yang terjadi selama sesi,
gunakan startTime dan endTime sesi untuk memfilter permintaan jenis data tersebut.
suspend fun readHeartRateData(
healthConnectClient: HealthConnectClient,
exerciseSession: ExerciseSessionRecord
) {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(
exerciseSession.startTime,
exerciseSession.endTime
)
)
)
for (heartRateRecord in response.records) {
for (sample in heartRateRecord.samples) {
val bpm = sample.beatsPerMinute
}
}
}
Praktik terbaik
Ikuti panduan berikut untuk meningkatkan keandalan data dan pengalaman pengguna:
- Frekuensi Penulisan
- Pelacakan Aktif(Latar Depan): Untuk latihan fisik aktif, tulis data saat tersedia atau pada interval maksimum 15 menit.
- Sinkronisasi Latar Belakang: Gunakan
WorkManageruntuk penulisan yang ditangguhkan. Tetapkan interval 15 menit untuk menyeimbangkan data real-time dan efisiensi baterai. - Batching: Jangan tulis setiap peristiwa sensor satu per satu. Bagi permintaan Anda menjadi beberapa bagian. Health Connect menangani hingga 1.000 data per permintaan penulisan.
- Menjaga ID sesi tetap stabil dan unik: Gunakan ID yang konsisten untuk sesi Anda. Jika sesi diedit atau diperbarui, penggunaan ID yang sama akan mencegah sesi tersebut diperlakukan sebagai latihan fisik baru yang terpisah.
- Gunakan batching untuk jenis data dan titik rute: Untuk mengurangi
overhead Input/Output dan menghemat masa pakai baterai, kelompokkan titik data
ke dalam satu panggilan
insertRecords, bukan menulis setiap titik secara terpisah. Menghindari penulisan data duplikat: Gunakan ID Klien Saat membuat catatan, tetapkan
metadata.clientRecordId. Health Connect menggunakan ini untuk mengidentifikasi catatan unik. Jika Anda mencoba menulis data denganclientRecordIdyang sudah ada, Health Connect akan mengabaikan duplikat atau memperbarui data yang ada, bukan membuat data baru. Menetapkanmetadata.clientRecordIdadalah cara paling efektif untuk mencegah duplikat selama percobaan ulang sinkronisasi atau penginstalan ulang aplikasi.val record = StepsRecord( count = 100, startTime = startTime, endTime = endTime, startZoneOffset = ZoneOffset.UTC, endZoneOffset = ZoneOffset.UTC, metadata = Metadata( // Use a unique ID from your own database clientRecordId = "daily_steps_2023_10_27_user_123" ) )Periksa data yang ada: Sebelum menyinkronkan, kueri rentang waktu untuk melihat apakah data dari aplikasi Anda sudah ada.
Validasi akurasi GPS: Memfilter sampel GPS dengan akurasi rendah (Misalnya, titik dengan radius akurasi horizontal tinggi) sebelum menulis ke
ExerciseRouteuntuk memverifikasi bahwa peta terlihat bersih dan profesional.Pastikan stempel waktu tidak tumpang-tindih: Verifikasi bahwa sesi baru tidak dimulai sebelum sesi sebelumnya berakhir. Sesi yang tumpang-tindih dapat menyebabkan konflik di dasbor kebugaran dan penghitungan ringkasan.
Berikan alasan yang jelas untuk izin: Gunakan alur
Permission.createIntentuntuk menjelaskan alasan aplikasi Anda memerlukan akses ke data kesehatan, seperti "Untuk memetakan lari Anda dan menghitung pembakaran kalori".Mendukung jeda dan lanjutkan: Pastikan aplikasi Anda menangani jeda dengan benar. Saat pengguna menjeda, hentikan pengumpulan titik rute dan jenis data agar kecepatan dan durasi rata-rata tetap akurat.
Uji sesi yang berjalan lama: Pantau konsumsi baterai selama sesi yang berlangsung beberapa jam untuk memverifikasi bahwa interval batching dan penggunaan sensor Anda tidak menguras baterai perangkat.
Menyelaraskan stempel waktu dengan kecepatan sensor: Cocokkan stempel waktu rekaman Anda dengan frekuensi sebenarnya sensor Anda (misalnya, 1 Hz untuk GPS) untuk mempertahankan fidelitas tinggi data.
Pengujian
Untuk memverifikasi kebenaran data dan pengalaman pengguna yang berkualitas tinggi, ikuti strategi pengujian berikut dan lihat dokumentasi Uji kasus penggunaan teratas resmi.
Alat verifikasi
- Toolbox Health Connect: Gunakan aplikasi pendamping ini untuk memeriksa catatan secara manual, menghapus data pengujian, dan menyimulasikan perubahan pada database. Cara ini adalah cara terbaik untuk memverifikasi bahwa catatan Anda disimpan dengan benar.
- Pengujian unit dengan
FakeHealthConnectClient: Gunakan library pengujian untuk memverifikasi cara aplikasi Anda menangani kasus ekstrem, seperti pencabutan izin atau pengecualian API tanpa memerlukan perangkat fisik.
Checklist kualitas
Arsitektur umum
Penerapan latihan fisik biasanya mencakup:
| Komponen | Mengelola |
|---|---|
| Pengontrol sesi | Status sesi Timer Logika pengelompokan Pengontrol jenis data Pengambilan sampel lokasi |
| Lapisan repositori (membungkus operasi Health Connect:) | Menyisipkan sesi Menyisipkan jenis data Menyisipkan titik rute Membaca ringkasan sesi |
| Lapisan UI (Tampilan): | Durasi Jenis data langsung Pratinjau peta Perhitungan terpisah Jalur GPS Langsung |
Pemecahan masalah
| Gejala | Kemungkinan penyebab | Resolusi |
|---|---|---|
| Rute tidak terkait dengan sesi | ID sesi atau rentang waktu tidak cocok. | Pastikan ExerciseRoute ditulis dengan rentang waktu yang sepenuhnya berada dalam durasi ExerciseSessionRecord. Pastikan Anda menggunakan ID yang konsisten jika merujuk ke sesi nanti. Lihat Merekam rute latihan. |
| Jenis data tidak ada (misalnya, Detak Jantung) | Izin tulis tidak ada atau filter waktu salah. | Pastikan Anda telah meminta dan pengguna telah memberikan izin jenis data tertentu. Pastikan ReadRecordsRequest Anda menggunakan TimeRangeFilter yang cocok dengan sesi. Lihat Izin. |
| Sesi gagal menulis | Stempel waktu yang tumpang-tindih. | Health Connect dapat menolak data yang tumpang-tindih dengan data yang ada dari aplikasi yang sama. Pastikan startTime sesi baru berada setelah endTime sesi sebelumnya. |
| Tidak ada data GPS yang direkam | Layanan latar depan dihentikan atau tidak aktif. | Untuk mengumpulkan data saat layar nonaktif, Anda harus menggunakan Layanan Latar Depan dengan atribut foregroundServiceType="health" atau lokasi. |
| Record duplikat muncul | clientRecordId tidak ada. |
Tetapkan clientRecordId unik di Metadata setiap data. Hal ini memungkinkan Health Connect melakukan penghapusan duplikat jika data yang sama ditulis dua kali selama percobaan ulang sinkronisasi. Lihat Praktik terbaik. |
Langkah-langkah umum proses penelusuran kesalahan
| Periksa status izin. | Selalu panggil getPermissionStatus() sebelum mencoba operasi baca atau tulis. Pengguna dapat mencabut izin di setelan sistem kapan saja. |
| Verifikasi mode eksekusi. | Jika aplikasi Anda tidak mengumpulkan data di latar belakang, pastikan Anda telah mendeklarasikan izin yang benar dalam file AndroidManifest.xml dan pengguna belum menempatkan aplikasi ke mode "Dibatasi Baterai". |