Melacak langkah

Health Connect menyediakan jenis data langkah untuk mencatat jumlah langkah menggunakan StepsRecord. Langkah adalah pengukuran mendasar dalam pemantauan kesehatan dan kebugaran.

Membaca langkah seluler

Dengan Android 14 (level API 34) dan Ekstensi SDK versi 20 atau yang lebih tinggi, Health Connect menyediakan penghitungan langkah di perangkat. Jika aplikasi telah diberi izin READ_STEPS, Health Connect akan mulai merekam langkah dari perangkat berteknologi Android, dan pengguna akan melihat data langkah yang otomatis ditambahkan ke entri Langkah Health Connect.

Untuk memeriksa apakah penghitungan langkah di perangkat tersedia, Anda harus memverifikasi bahwa perangkat menjalankan Android 14 (level API 34) dan memiliki setidaknya ekstensi SDK versi 20. Anda dapat menggunakan kode berikut:

val isStepTrackingAvailable =
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
        SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20

Langkah seluler yang direkam oleh Health Connect memiliki DataOrigin yang ditetapkan ke nama paket android. Jika aplikasi Anda hanya membaca jumlah langkah yang digabungkan menggunakan aggregate dan tidak memfilter menurut DataOrigin, langkah di perangkat akan otomatis disertakan dalam total.

Jika aplikasi Anda perlu membaca langkah-langkah di perangkat, atau jika aplikasi menampilkan data langkah yang dikelompokkan menurut aplikasi atau perangkat sumber, Anda dapat membuat kueri untuk data saat DataOrigin adalah android. Jika aplikasi Anda menampilkan atribusi untuk data langkah, Anda harus mengatribusikan data dari paket android ke perangkat saat ini. Anda dapat melakukannya dengan menggunakan label seperti "Ponsel Anda", mengambil nama perangkat dengan Settings.Global.getString(resolver, Settings.Global.DEVICE_NAME), atau memeriksa kolom Device dalam metadata rekaman.

Contoh berikut menunjukkan cara membaca data jumlah langkah seluler gabungan dengan memfilter asal data android:

suspend fun readStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
                dataOriginFilter = setOf(DataOrigin("android"))
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

Penghitungan Langkah di Perangkat

Mempelajari lebih dalam fitur penghitungan langkah di perangkat:

  • Penggunaan Sensor: Health Connect menggunakan sensor TYPE_STEP_COUNTER dari SensorManager. Sensor ini dioptimalkan untuk konsumsi daya rendah, sehingga ideal untuk pelacakan langkah di latar belakang secara berkelanjutan.
  • Perincian Data: Untuk menghemat masa pakai baterai, data langkah biasanya dikelompokkan dan ditulis ke database Health Connect tidak lebih sering dari sekali per menit.
  • Atribusi: Seperti yang disebutkan sebelumnya, semua langkah yang direkam oleh fitur di perangkat ini diatribusikan ke nama paket android dalam DataOrigin.
  • Aktivasi: Mekanisme penghitungan langkah di perangkat hanya aktif jika setidaknya satu aplikasi di perangkat telah diberi izin READ_STEPS dalam Health Connect.

Memeriksa ketersediaan Health Connect

Sebelum mencoba menggunakan Health Connect, aplikasi Anda harus memverifikasi bahwa Health Connect tersedia di perangkat pengguna. Health Connect mungkin tidak diinstal di semua perangkat atau dapat dinonaktifkan. Anda dapat memeriksa ketersediaan menggunakan metode HealthConnectClient.getSdkStatus().

Cara memeriksa ketersediaan Health Connect

fun checkHealthConnectAvailability(context: Context) {
    val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME
    val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)

    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
      // Health Connect is not available. Guide the user to install/enable it.
      // For example, show a dialog.
      return // early return as there is no viable integration
    }
    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
      // Health Connect is available but requires an update.
      // Optionally redirect to package installer to find a provider, for example:
      val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
      context.startActivity(
        Intent(Intent.ACTION_VIEW).apply {
          setPackage("com.android.vending")
          data = Uri.parse(uriString)
          putExtra("overlay", true)
          putExtra("callerId", context.packageName)
        }
      )
      return
    }
    // Health Connect is available, obtain a HealthConnectClient instance
    val healthConnectClient = HealthConnectClient.getOrCreate(context)
    // Issue operations with healthConnectClient
}

Bergantung pada status yang ditampilkan oleh getSdkStatus(), Anda dapat memandu pengguna untuk menginstal atau mengupdate Health Connect dari Google Play Store jika perlu.

Izin yang diperlukan

Akses ke langkah dilindungi oleh izin berikut:

  • android.permission.health.READ_STEPS
  • android.permission.health.WRITE_STEPS

Untuk menambahkan kemampuan langkah ke aplikasi Anda, mulailah dengan meminta izin tulis untuk jenis data Steps.

Berikut adalah izin yang harus Anda deklarasikan agar dapat menulis langkah:

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

Untuk membaca langkah-langkah, Anda perlu meminta izin berikut:

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

Meminta izin dari pengguna

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(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 harus memeriksa izin yang diberikan secara berkala dan menangani skenario saat izin tersebut hilang.

Informasi yang disertakan dalam data Langkah

Setiap StepsRecord berisi informasi berikut:

  • count: Jumlah langkah yang dilakukan dalam interval waktu, sebagai Long.
  • startTime: Waktu mulai interval pengukuran.
  • endTime: Waktu berakhir interval pengukuran.
  • startZoneOffset: Perbedaan zona untuk waktu mulai.
  • endZoneOffset: Perbedaan zona untuk waktu berakhir.

Agregasi yang didukung

Nilai gabungan berikut tersedia untuk StepsRecord:

Nilai gabungan berikut tersedia untuk StepsCadenceRecord:

Contoh penggunaan

Bagian berikut menunjukkan cara membaca dan menulis data StepsRecord.

Menulis data langkah

Aplikasi Anda dapat menulis data jumlah langkah dengan menyisipkan instance StepsRecord. Contoh berikut menunjukkan cara merekam 1.000 langkah yang dilakukan pengguna:

suspend fun writeStepsData(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant,
    startZoneOffset: ZoneOffset,
    endZoneOffset: ZoneOffset
) {
    try {
        val stepsRecord = StepsRecord(
            startTime = startTime,
            startZoneOffset = startZoneOffset,
            endTime = endTime,
            endZoneOffset = endZoneOffset,
            count = 1000
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling
    }
}

Membaca data gabungan

Cara paling umum untuk membaca data langkah adalah dengan menggabungkan total langkah selama jangka waktu tertentu. Contoh berikut menunjukkan cara membaca total jumlah langkah untuk pengguna dalam rentang waktu tertentu:

suspend fun readStepsAggregate(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

Membaca data mentah

Contoh berikut menunjukkan cara membaca data StepsRecord mentah antara waktu mulai dan berakhir:

suspend fun readStepsRaw(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        for (record in response.records) {
            // Process each record
        }
    } catch (e: Exception) {
        // Run error handling here
    }
}