Merekam latihan dengan ExerciseClient

Fitur Kesehatan memberikan dukungan terbaik untuk aplikasi olahraga melalui ExerciseClient. Dengan ExerciseClient, aplikasi Anda dapat mengontrol kapan latihan sedang berlangsung, menambahkan target latihan, dan mendapatkan update terkait status latihan peristiwa latihan atau metrik lain yang diinginkan. Untuk informasi selengkapnya, lihat daftar lengkap jenis latihan yang didukung Fitur Kesehatan.

Lihat Contoh latihan di GitHub.

Menambahkan dependensi

Untuk menambahkan dependensi di Fitur Kesehatan, Anda harus menambahkan repositori Maven Google ke project Anda. Untuk mengetahui informasi selengkapnya, lihat Repositori Maven Google.

Kemudian, di file build.gradle tingkat modul, tambahkan dependensi berikut:

Groovy

dependencies {
    implementation "androidx.health:health-services-client:1.1.0-alpha05"
}

Kotlin

dependencies {
    implementation("androidx.health:health-services-client:1.1.0-alpha05")
}

Struktur aplikasi

Gunakan struktur aplikasi berikut saat mengembangkan aplikasi latihan dengan Fitur Kesehatan:

Saat menyiapkan olahraga dan selama olahraga, aktivitas Anda mungkin dihentikan karena berbagai alasan. Pengguna mungkin beralih ke aplikasi lain atau kembali ke tampilan jam. Sistem mungkin menampilkan sesuatu di atas aktivitas Anda, atau layar mungkin mati setelah tidak aktif selama periode tertentu. Gunakan ForegroundService yang terus berjalan bersama dengan ExerciseClient untuk memastikan operasi yang benar selama sesi olahraga.

Penggunaan ForegroundService memungkinkan Anda menggunakan Ongoing Activity API untuk menampilkan indikator pada platform smartwatch dan memungkinkan pengguna kembali ke latihan dengan cepat.

Anda harus meminta data lokasi dengan tepat di layanan latar depan. Di file manifes, tentukan layanan latar depan yang diperlukan jenis konten dan izin:

<manifest ...>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application ...>
    
      <!-- If your app is designed only for devices that run Wear OS 4
           or lower, use android:foregroundServiceType="location" instead. -->
      <service
          android:name=".MyExerciseSessionRecorder"
          android:foregroundServiceType="health|location">
      </service>
      
    </application>
</manifest>

Gunakan AmbientLifecycleObserver untuk aktivitas pra-olahraga Anda, yang berisi panggilan prepareExercise() dan untuk aktivitas olahraga Anda. Namun, jangan perbarui tampilan selama olahraga dalam mode standby: Ini karena Fitur Kesehatan mengelompokkan data olahraga saat layar perangkat dalam mode standby untuk menghemat daya, sehingga informasi yang ditampilkan mungkin bukan yang terbaru. Selama olahraga, tampilkan data yang masuk akal bagi pengguna, yang menampilkan informasi terbaru atau layar kosong.

Memeriksa kemampuan

Setiap ExerciseType mendukung jenis data tertentu untuk metrik dan untuk target latihan. Periksa kemampuan ini saat memulai, karena kemampuan tersebut dapat bervariasi bergantung pada perangkat. Perangkat mungkin tidak mendukung jenis latihan tertentu, atau mungkin tidak mendukung fungsi tertentu, seperti jeda otomatis. Selain itu, kemampuan perangkat dapat berubah seiring waktu, seperti setelah update software.

Saat memulai aplikasi, buat kueri terkait kemampuan perangkat, lalu simpan dan proses hal berikut:

  • Latihan yang didukung platform.
  • Fitur yang didukung untuk setiap latihan.
  • Jenis data yang didukung untuk setiap latihan.
  • Izin yang diperlukan untuk setiap jenis data tersebut.

Gunakan ExerciseCapabilities.getExerciseTypeCapabilities() dengan jenis latihan yang Anda inginkan untuk melihat jenis metrik yang dapat Anda minta, target latihan mana yang dapat Anda konfigurasi, dan fitur lain yang tersedia untuk jenis tersebut. Hal ini ditunjukkan dalam contoh berikut:

val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
    val capabilities = exerciseClient.getCapabilitiesAsync().await()
    if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
        runningCapabilities =
            capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
    }
}

Di dalam ExerciseTypeCapabilities yang ditampilkan, supportedDataTypes mencantumkan jenis data yang dapat Anda minta datanya. Opsi ini bervariasi menurut perangkat, jadi pastikan untuk tidak meminta DataType yang tidak didukung, atau permintaan Anda akan gagal.

Gunakan kolom supportedGoals dan supportedMilestones untuk menentukan apakah latihan dapat mendukung target latihan yang hendak dibuat.

Jika aplikasi memungkinkan pengguna menggunakan jeda otomatis, Anda harus memeriksa apakah fungsi ini didukung oleh perangkat menggunakan supportsAutoPauseAndResume. ExerciseClient menolak permintaan yang tidak didukung di perangkat.

Contoh berikut memeriksa dukungan untuk jenis data HEART_RATE_BPM, kemampuan sasaran STEPS_TOTAL, dan fungsi jeda otomatis:

// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes

// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals = 
    (stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)

// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume

Mendaftar untuk pembaruan status olahraga

Pembaruan olahraga dikirim ke pemroses. Aplikasi Anda hanya dapat mendaftarkan pemroses satu per satu. Siapkan pemroses Anda sebelum memulai olahraga, seperti yang ditunjukkan pada contoh berikut. Pemroses Anda hanya menerima update tentang olahraga yang dimiliki aplikasi Anda.

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        val exerciseStateInfo = update.exerciseStateInfo
        val activeDuration = update.activeDurationCheckpoint
        val latestMetrics = update.latestMetrics
        val latestGoals = update.latestAchievedGoals
    }

    override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
        // For ExerciseTypes that support laps, this is called when a lap is marked.
    }

    override fun onAvailabilityChanged(
        dataType: DataType<*, *>,
        availability: Availability
    ) {
        // Called when the availability of a particular DataType changes.
        when {
            availability is LocationAvailability -> // Relates to Location/GPS.
            availability is DataTypeAvailability -> // Relates to another DataType.
        }
    }
}
exerciseClient.setUpdateCallback(callback)

Mengelola masa pakai olahraga

Fitur Kesehatan mendukung maksimum satu olahraga dalam satu waktu di semua aplikasi pada perangkat. Jika olahraga sedang dilacak dan aplikasi yang berbeda mulai melacak olahraga baru, olahraga pertama akan dihentikan.

Sebelum memulai latihan, lakukan hal berikut:

  • Periksa apakah olahraga sudah dilacak, dan bereaksi sebagaimana mestinya. Misalnya, meminta konfirmasi pengguna sebelum mengganti latihan sebelumnya dan mulai melacak latihan baru.

Contoh berikut menunjukkan cara memeriksa latihan yang sudah ada dengan getCurrentExerciseInfoAsync:

lifecycleScope.launch {
    val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
    when (exerciseInfo.exerciseTrackedStatus) {
        OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
        OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
        NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
    }
}

Izin

Saat menggunakan ExerciseClient, pastikan aplikasi Anda meminta dan mempertahankan izin yang diperlukan. Jika aplikasi Anda menggunakan data LOCATION, pastikan aplikasi Anda meminta dan mempertahankan izin akses yang sesuai untuk itu juga.

Untuk semua jenis data, sebelum memanggil prepareExercise() atau startExercise(), lakukan hal berikut:

  • Tentukan izin yang sesuai untuk jenis data yang diminta di file AndroidManifest.xml Anda.
  • Verifikasi bahwa pengguna telah memberikan izin yang diperlukan. Untuk mengetahui informasi selengkapnya, lihat Meminta izin aplikasi. Fitur Kesehatan menolak permintaan jika izin yang diperlukan belum diberikan.

Untuk data lokasi, lakukan langkah-langkah tambahan berikut:

Bersiap untuk olahraga

Beberapa sensor, seperti GPS atau detak jantung, mungkin memerlukan waktu singkat untuk pemanasan, atau pengguna mungkin ingin melihat data mereka sebelum memulai olahraga. Metode prepareExerciseAsync() opsional memungkinkan sensor melakukan pemanasan dan data diterima tanpa memulai penghitung waktu untuk olahraga. activeDuration tidak terpengaruh oleh waktu persiapan ini.

Sebelum melakukan panggilan ke prepareExerciseAsync(), periksa hal berikut:

  • Periksa setelan lokasi di seluruh platform. Pengguna mengontrol setelan ini di menu Setelan utama; pemeriksaan ini berbeda dengan pemeriksaan izin tingkat aplikasi.

    Jika setelan ini tidak aktif, beri tahu pengguna bahwa mereka telah menolak akses ke lokasi dan minta mereka untuk mengaktifkannya jika aplikasi Anda memerlukan lokasi.

  • Konfirmasi bahwa aplikasi Anda memiliki izin runtime untuk sensor tubuh, pengenalan aktivitas, dan lokasi. Untuk izin yang tidak ada, minta pengguna untuk memberikan izin runtime dengan memberikan konteks yang memadai. Jika pengguna tidak memberikan izin tertentu, hapus jenis data yang terkait dengan izin tersebut dari panggilan ke prepareExerciseAsync(). Jika tidak ada sensor tubuh atau izin akses lokasi tidak diberikan, jangan akses prepareExerciseAsync(), karena panggilan persiapan khusus dirancang untuk memperoleh detak jantung yang stabil atau posisi GPS sebelum memulai latihan. Aplikasi masih bisa mendapatkan jarak berbasis langkah, laju, kecepatan, dan metrik lainnya yang tidak memerlukan izin tersebut.

Lakukan hal berikut untuk memastikan panggilan ke prepareExerciseAsync() dapat berhasil:

  • Gunakan AmbientLifecycleObserver untuk aktivitas pra-olahraga Anda yang berisi panggilan persiapan.
  • Panggil prepareExerciseAsync() dari layanan latar depan Anda. Jika tidak berada dalam layanan dan terikat dengan siklus proses aktivitas, persiapan sensor mungkin harus dihentikan.
  • Panggil endExercise() untuk menonaktifkan sensor dan mengurangi penggunaan daya jika pengguna keluar dari aktivitas pra-olahraga.

Contoh berikut menunjukkan cara memanggil prepareExerciseAsync():

val warmUpConfig = WarmUpConfig(
    ExerciseType.RUNNING,
    setOf(
        DataType.HEART_RATE_BPM,
        DataType.LOCATION
    )
)
// Only necessary to call prepareExerciseAsync if body sensor or location
//permissions are given
exerciseClient.prepareExerciseAsync(warmUpConfig).await()

// Data and availability updates are delivered to the registered listener.

Setelah aplikasi berada dalam status PREPARING, update ketersediaan sensor akan dikirimkan di ExerciseUpdateCallback melalui onAvailabilityChanged(). Informasi ini kemudian dapat ditampilkan kepada pengguna sehingga mereka dapat memutuskan apakah akan memulai olahraga mereka atau tidak.

Memulai olahraga

Jika Anda ingin memulai olahraga, buat ExerciseConfig untuk mengonfigurasi jenis olahraga, jenis data yang metriknya ingin Anda terima, dan target atau pencapaian olahraga.

Target olahraga terdiri dari DataType dan kondisi. Target olahraga adalah target satu kali yang dipicu saat suatu kondisi terpenuhi, seperti saat pengguna menjalankan jarak tertentu. Tonggak pencapaian olahraga juga dapat ditetapkan. Tonggak pencapaian olahraga dapat dipicu beberapa kali, seperti setiap kali pengguna menjalankan titik tertentu setelah jarak yang ditetapkan.

Contoh berikut menunjukkan cara membuat satu sasaran untuk setiap jenis:

const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters

suspend fun startExercise() {
    // Types for which we want to receive metrics.
    val dataTypes = setOf(
        DataType.HEART_RATE_BPM,
        DataType.CALORIES_TOTAL,
        DataType.DISTANCE
    )

    // Create a one-time goal.
    val calorieGoal = ExerciseGoal.createOneTimeGoal(
        DataTypeCondition(
            dataType = DataType.CALORIES_TOTAL,
            threshold = CALORIES_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        )
    )

    // Create a milestone goal. To make a milestone for every kilometer, set the initial
    // threshold to 1km and the period to 1km.
    val distanceGoal = ExerciseGoal.createMilestone(
        condition = DataTypeCondition(
            dataType = DataType.DISTANCE_TOTAL,
            threshold = DISTANCE_THRESHOLD,
            comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
        ),
        period = DISTANCE_THRESHOLD
    )

    val config = ExerciseConfig(
        exerciseType = ExerciseType.RUNNING,
        dataTypes = dataTypes,
        isAutoPauseAndResumeEnabled = false,
        isGpsEnabled = true,
        exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
    )
    exerciseClient.startExerciseAsync(config).await()
}

Anda juga dapat menandai putaran untuk semua latihan. Fitur Kesehatan menyediakan ExerciseLapSummary dengan metrik yang digabungkan selama periode putaran.

Contoh sebelumnya menunjukkan penggunaan isGpsEnabled, yang harus benar saat meminta data lokasi. Namun, menggunakan GPS dapat membantu dengan metrik lainnya. Jika ExerciseConfig menentukan jarak sebagai DataType, setelan ini akan menggunakan langkah-langkah untuk memperkirakan jarak secara default. Dengan mengaktifkan GPS secara opsional, informasi lokasi dapat digunakan untuk memperkirakan jarak.

Menjeda, melanjutkan, dan mengakhiri olahraga

Anda dapat menjeda, melanjutkan, dan mengakhiri olahraga menggunakan metode yang sesuai, seperti pauseExerciseAsync() atau endExerciseAsync().

Gunakan status dari ExerciseUpdate sebagai sumber kebenaran. Olahraga tidak dianggap dijeda saat panggilan ke pauseExerciseAsync() ditampilkan, tetapi saat status tersebut tercermin dalam pesan ExerciseUpdate. Hal ini sangat penting untuk dipertimbangkan saat berkaitan dengan status UI. Jika pengguna menekan jeda, nonaktifkan tombol jeda dan panggil pauseExerciseAsync() di Fitur Kesehatan. Tunggu hingga Fitur Kesehatan mencapai status dijeda menggunakan ExerciseUpdate.exerciseStateInfo.state, lalu alihkan tombol untuk melanjutkan. Hal ini karena update status Fitur Kesehatan dapat memerlukan waktu lebih lama untuk dikirimkan daripada menekan tombol, sehingga jika Anda mengaitkan semua perubahan UI ke penekanan tombol, UI mungkin tidak akan sinkron dengan status Fitur Kesehatan.

Perhatikan situasi berikut ini:

  • Jeda otomatis diaktifkan: olahraga dapat dijeda atau dimulai tanpa interaksi pengguna.
  • Aplikasi lain memulai olahraga: olahraga Anda dapat dihentikan tanpa interaksi pengguna.

Jika olahraga aplikasi Anda dihentikan oleh aplikasi lain, aplikasi Anda harus menangani penghentian tersebut dengan baik:

  • Menyimpan status latihan parsial agar progres pengguna tidak dihapus.
  • Hapus ikon Aktivitas Berkelanjutan dan kirim notifikasi kepada pengguna yang memberitahukan bahwa olahraga mereka diakhiri oleh aplikasi lain.

Selain itu, tangani kasus jika izin dicabut selama olahraga yang sedang berlangsung. Ini dikirim menggunakan status isEnded, dengan ExerciseEndReason dari AUTO_END_PERMISSION_LOST. Tangani kasus ini dengan cara yang sama seperti kasus penghentian: simpan status parsial, hapus ikon Aktivitas yang Sedang Berlangsung, dan kirim notifikasi tentang apa yang terjadi pada pengguna.

Contoh berikut menunjukkan cara memeriksa penghentian dengan benar:

val callback = object : ExerciseUpdateCallback {
    override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
        if (update.exerciseStateInfo.state.isEnded) {
            // Workout has either been ended by the user, or otherwise terminated
        }
        ...
    }
    ...
}

Mengelola durasi aktif

Selama olahraga, aplikasi dapat menampilkan durasi aktif olahraga. Aplikasi, Fitur Kesehatan, dan Unit Pengontrol Mikro perangkat (MCU)—daya rendah prosesor bertanggung jawab untuk pelacakan olahraga—semuanya harus sinkron, dengan durasi aktif saat ini yang sama. Untuk membantu mengelolanya, Fitur Kesehatan mengirimkan ActiveDurationCheckpoint yang menyediakan titik link dari tempat aplikasi dapat memulai timer-nya.

Karena durasi aktif dikirim dari MCU dan dapat memerlukan sedikit waktu untuk masuk ke aplikasi, ActiveDurationCheckpoint berisi dua properti:

  • activeDuration: berapa lama olahraga telah aktif
  • time: saat durasi aktif di atas dihitung

Oleh karena itu, di aplikasi, durasi aktif olahraga dapat dihitung dari ActiveDurationCheckpoint menggunakan persamaan berikut:

(now() - checkpoint.time) + checkpoint.activeDuration

Hal ini akan memperhitungkan delta kecil antara durasi aktif yang dihitung di MCU, dan tiba di aplikasi. Hal ini dapat digunakan untuk menambahkan kronometer dalam aplikasi dan akan memastikan bahwa timer aplikasi benar-benar selaras dengan waktu di Fitur Kesehatan dan MCU.

Jika olahraga dijeda, aplikasi menunggu untuk memulai ulang timer di UI hingga waktu yang dihitung telah melewati UI yang saat ini ditampilkan. Hal ini karena sinyal jeda mencapai Fitur Kesehatan dan MCU dengan sedikit keterlambatan. Misalnya, jika aplikasi dijeda pada t=10 detik, Fitur Kesehatan mungkin tidak mengirimkan update PAUSED ke aplikasi hingga t=10,2 detik.

Menggunakan data dari ExerciseClient

Metrik untuk jenis data yang telah didaftarkan aplikasi Anda dikirim dalam pesan ExerciseUpdate .

Pemroses hanya mengirimkan pesan saat aktif atau saat periode pelaporan maksimum tercapai, misalnya setiap 150 detik. Jangan andalkan frekuensi ExerciseUpdate untuk memajukan kronometer dengan activeDuration. Lihat Contoh latihan di GitHub untuk mengetahui contoh cara mengimplementasikan kronometer independen.

Saat pengguna memulai olahraga, pesan ExerciseUpdate mungkin sering dikirim, misalnya setiap detik. Saat pengguna memulai olahraga, layar mungkin nonaktif. Fitur Kesehatan kemudian dapat lebih jarang mengirimkan data, tetapi masih diambil sampelnya dengan frekuensi yang sama, untuk menghindari pemroses utama. Saat pengguna melihat layar, data apa pun yang ada dalam proses pengelompokan akan segera dikirimkan ke aplikasi Anda.

Mengontrol kecepatan pengelompokan

Dalam beberapa skenario, Anda mungkin ingin mengontrol frekuensi aplikasi menerima jenis data tertentu saat layar nonaktif. Objek BatchingMode memungkinkan aplikasi Anda mengganti perilaku pengelompokan default agar pengiriman data lebih sering.

Untuk mengonfigurasi tingkat pengelompokan, selesaikan langkah-langkah berikut:

  1. Periksa apakah definisi BatchingMode tertentu didukung oleh perangkat:

    // Confirm BatchingMode support to control heart rate stream to phone.
    suspend fun supportsHrWorkoutCompanionMode(): Boolean {
        val capabilities = exerciseClient.getCapabilities()
        return BatchingMode.HEART_RATE_5_SECONDS in
                capabilities.supportedBatchingModeOverrides
    }
    
  2. Tentukan bahwa objek ExerciseConfig harus menggunakan BatchingMode tertentu, seperti yang ditunjukkan dalam cuplikan kode berikut.

    val config = ExerciseConfig(
        exerciseType = ExerciseType.WORKOUT,
        dataTypes = setOf(
            DataType.HEART_RATE_BPM,
            DataType.TOTAL_CALORIES
        ),
        // ...
        batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    )
    
  3. Secara opsional, Anda dapat mengonfigurasi BatchingMode secara dinamis selama olahraga, bukan mempertahankan perilaku pengelompokan tertentu selama durasi olahraga:

    val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS)
    exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)
    
  4. Untuk menghapus BatchingMode yang disesuaikan dan kembali ke perilaku default, teruskan kumpulan kosong ke exerciseClient.overrideBatchingModesForActiveExercise().

Stempel waktu

Titik waktu setiap titik data mewakili durasi sejak perangkat di-booting. Untuk mengonversinya ke stempel waktu, lakukan langkah berikut:

val bootInstant =
    Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())

Nilai ini kemudian dapat digunakan dengan getStartInstant() atau getEndInstant() untuk setiap titik data.

Akurasi data

Beberapa jenis data mungkin memiliki informasi akurasi yang terkait dengan setiap titik data. Hal ini diwakili dalam properti accuracy.

Class HrAccuracy dan LocationAccuracy masing-masing dapat diisi untuk masing-masing jenis data HEART_RATE_BPM dan LOCATION. Jika ada, gunakan properti accuracy untuk menentukan apakah setiap titik data memiliki akurasi yang cukup untuk aplikasi Anda atau tidak.

Menyimpan dan mengupload data

Gunakan Room untuk mempertahankan data yang dikirim dari Fitur Kesehatan. Upload data terjadi di akhir olahraga menggunakan mekanisme seperti Work Manager. Hal ini memastikan bahwa panggilan jaringan untuk mengupload data ditunda hingga olahraga selesai, meminimalkan konsumsi daya selama olahraga dan menyederhanakan pekerjaan.

Daftar integrasi

Sebelum memublikasikan aplikasi yang menggunakan Fitur Kesehatan ExerciseClient, konsultasikan daftar periksa berikut untuk memastikan pengalaman pengguna Anda menghindari beberapa masalah umum. Pastikan bahwa:

  • Aplikasi Anda memeriksa kemampuannya jenis olahraga dan kemampuan perangkat setiap kali aplikasi berjalan. Dengan begitu, Anda dapat mendeteksi saat perangkat atau olahraga tertentu tidak mendukungnya jenis data yang dibutuhkan aplikasi Anda.
  • Anda meminta dan mengelola izin yang diperlukan dan menentukannya dalam file manifes Anda. Sebelum memanggil prepareExerciseAsync(), aplikasi Anda mengonfirmasi bahwa izin runtime diberikan.
  • Aplikasi Anda menggunakan getCurrentExerciseInfoAsync() untuk menangani kasus ketika:
    • Latihan sudah dilacak, dan aplikasi Anda akan mengganti latihan sebelumnya latihan.
    • Aplikasi lain telah menghentikan latihan Anda. Hal ini bisa terjadi ketika pengguna membuka kembali aplikasi, mereka akan melihat pesan yang menjelaskan bahwa latihan tersebut dihentikan karena ada aplikasi lain yang mengambil alih.
  • Jika Anda menggunakan data LOCATION:
    • Aplikasi Anda mempertahankan ForegroundService dengan foregroundServiceType selama durasi olahraga (termasuk panggilan persiapan).
    • Periksa apakah GPS diaktifkan pada perangkat menggunakan isProviderEnabled(LocationManager.GPS_PROVIDER), dan meminta pengguna untuk buka setelan lokasi jika diperlukan.
    • Untuk kasus penggunaan yang berat, ketika menerima data lokasi dengan latensi adalah hal yang sangat penting, pertimbangkan untuk mengintegrasikan antarmuka Fused Penyedia Lokasi (FLP) dan menggunakan datanya sebagai perbaikan lokasi awal. Saat lebih stabil informasi lokasi tersedia dari Fitur Kesehatan, gunakan lokasi dari FLP.
  • Jika aplikasi Anda memerlukan upload data, semua panggilan jaringan untuk mengupload data ditunda hingga latihan berakhir. Jika tidak, selama latihan, membuat panggilan jaringan yang diperlukan dengan hemat.