कदमों को ट्रैक करना

Health Connect, कदम का डेटा टाइप उपलब्ध कराता है. इससे StepsRecord का इस्तेमाल करके, कदमों की संख्या रिकॉर्ड की जा सकती है. कदमों की संख्या, सेहत और फ़िटनेस को ट्रैक करने के लिए एक बुनियादी मेज़रमेंट है.

मोबाइल पर चलते समय लिए गए कदमों का डेटा देखने की अनुमति दें

Android 14 (एपीआई लेवल 34) और एसडीके एक्सटेंशन के वर्शन 20 या इसके बाद के वर्शन के साथ, Health Connect उपयोगकर्ता के डिवाइस पर ही कदमों की गिनती करने की सुविधा देता है. अगर किसी ऐप्लिकेशन को READ_STEPS की अनुमति दी गई है, तो Health Connect, Android डिवाइस से कदमों की जानकारी इकट्ठा करना शुरू कर देता है. साथ ही, उपयोगकर्ताओं को Health Connect की कदम वाली एंट्री में, कदमों की जानकारी अपने-आप जुड़ती हुई दिखती है.

उपयोगकर्ता के डिवाइस पर कदमों की गिनती करने की सुविधा उपलब्ध है या नहीं, यह देखने के लिए पक्का करें कि डिवाइस पर Android 14 (एपीआई लेवल 34) चल रहा हो और उसमें एसडीके एक्सटेंशन का कम से कम वर्शन 20 हो:

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

अगर आपका ऐप्लिकेशन, aggregate का इस्तेमाल करके कुल कदमों की संख्या को पढ़ता है और DataOrigin के हिसाब से फ़िल्टर नहीं करता है, तो उपयोगकर्ता के डिवाइस पर गिने गए कदम अपने-आप कुल कदमों की संख्या में शामिल हो जाते हैं. साथ ही, जून 2026 के अपडेट के लिए कोई बदलाव करने की ज़रूरत नहीं होती.

उपयोगकर्ता के डिवाइस पर किए गए चरणों के लिए एट्रिब्यूशन में बदलाव

जून 2026 के अपडेट से, Health Connect में नेटिव तौर पर ट्रैक किए गए चरणों को सिंथेटिक पैकेज नेम (एसपीएन) एट्रिब्यूट किया जाता है. जैसे, com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.

पहले, बिल्ट-इन चरणों को पैकेज के नाम android के लिए एट्रिब्यूट किया जाता था. जून 2026 से पहले रिकॉर्ड किए गए कदमों के पुराने डेटा में, android पैकेज का नाम सेव रहता है.

एसपीएन, डिवाइस के हिसाब से होते हैं. साथ ही, उपयोगकर्ता की निजता को सुरक्षित रखने के लिए, इन्हें हर ऐप्लिकेशन के हिसाब से तय किया जाता है:

  • स्टेबल: इसका मतलब है कि मौजूदा डिवाइस के लिए एसपीएन, आपके ऐप्लिकेशन के लिए स्टेबल है.
  • ऐप्लिकेशन के स्कोप में: एक ही डिवाइस पर मौजूद अलग-अलग ऐप्लिकेशन, उपयोगकर्ता के डिवाइस पर मौजूद स्टेप डेटा के लिए अलग-अलग एसपीएन देखते हैं.

डिवाइस पर किए जाने वाले चरणों के बारे में क्वेरी करना

एसपीएन, स्कोप किए जाते हैं और डिवाइस के हिसाब से अलग-अलग होते हैं. इसलिए, आपको एसपीएन की वैल्यू को हार्डकोड नहीं करना चाहिए. इसके बजाय, मौजूदा डिवाइस के लिए एसपीएन पाने के लिए, getCurrentDeviceDataSource एपीआई का इस्तेमाल करें.

डिवाइस पर कदमों की गिनती करने के लिए, एसडीके एक्सटेंशन का वर्शन 20 या इसके बाद का होना ज़रूरी है. हालांकि, getCurrentDeviceDataSource() एपीआई, Android 14 (एपीआई लेवल 34) पर एसडीके एक्सटेंशन के वर्शन 22 या इसके बाद के वर्शन के साथ उपलब्ध है. इस एपीआई का इस्तेमाल करने के लिए, मॉड्यूल-लेवल की build.gradle.kts या build.gradle फ़ाइल में compileSdkExtension को 22 या इसके बाद के वर्शन पर सेट करें:

Kotlin

android {
    compileSdk = 35
    compileSdkExtension = 22
}

Groovy

android {
    compileSdk 35
    compileSdkExtension 22
}

getCurrentDeviceDataSource() API, फ़िलहाल Health Connect Jetpack लाइब्रेरी में उपलब्ध नहीं है. यहां दिए गए उदाहरणों में, Android फ़्रेमवर्क एपीआई का इस्तेमाल किया गया है. इसके लिए, Executor और OutcomeReceiver कॉलबैक की ज़रूरत होती है:

import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.OutcomeReceiver

val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
healthConnectManager?.getCurrentDeviceDataSource(
    context.mainExecutor,
    object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
        override fun onResult(result: DeviceDataSource) {
            val currentDeviceSpn = result.deviceDataOrigin.packageName
        }

        override fun onError(error: HealthConnectException) {
            // Handle error
        }
    }
)

अगर आपके ऐप्लिकेशन को डिवाइस पर मौजूद कदमों की संख्या को पढ़ना है या वह सोर्स ऐप्लिकेशन या डिवाइस के हिसाब से कदमों की संख्या का डेटा दिखाता है, तो आपको उन रिकॉर्ड के लिए क्वेरी करनी होगी जिनमें DataOrigin android या डिवाइस के एसपीएन से मेल खाता हो. अगर आपका ऐप्लिकेशन, गतिविधि के डेटा के लिए एट्रिब्यूशन दिखाता है, तो अलग-अलग रिकॉर्ड के लिए सोर्स डिवाइस की पहचान करने के लिए, metadata.device का इस्तेमाल करें. एसपीएन से पहचाने गए डिवाइस पर किए गए चरणों के लिए, एग्रीगेट किए गए डेटा में डिवाइस के मेटाडेटा का इस्तेमाल किया जा सकता है. जैसे, एट्रिब्यूशन के लिए DeviceDataSource से model या manufacturer का इस्तेमाल करें. इसके अलावा, डिवाइस पर किए गए चरणों के लिए, "आपका फ़ोन" जैसे सामान्य लेबल का इस्तेमाल करें.

यहां दिए गए उदाहरण में, डिवाइस पर मौजूद कुल कदमों की संख्या के डेटा को पढ़ने का तरीका बताया गया है. इसके लिए, android और मौजूदा डिवाइस के एसपीएन, दोनों के हिसाब से फ़िल्टर किया गया है:

import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.OutcomeReceiver
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine

suspend fun readDeviceStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    context: Context,
    startTime: Instant,
    endTime: Instant
) {
    // 1. Check if SDK Extension 22+ is available for getCurrentDeviceDataSource()
    val isDataSourceApiAvailable =
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
            SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 22

    try {
        val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)

        // 2. Safely fetch the package name only if the API is available
        val currentDeviceSpn = if (isDataSourceApiAvailable && healthConnectManager != null) {
            suspendCancellableCoroutine { continuation ->
                healthConnectManager.getCurrentDeviceDataSource(
                    context.mainExecutor,
                    object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
                        override fun onResult(result: DeviceDataSource) {
                            continuation.resume(result.deviceDataOrigin.packageName)
                        }

                        override fun onError(error: HealthConnectException) {
                            continuation.resumeWithException(error)
                        }
                    }
                )
            }
        } else {
            null
        }

        val dataOriginFilters = mutableSetOf(DataOrigin("android"))

        // 3. Explicit null-safety check using .let
        currentDeviceSpn?.let {
            dataOriginFilters.add(DataOrigin(it))
        }

        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
                dataOriginFilter = dataOriginFilters
            )
        )

        val stepCount = response[StepsRecord.COUNT_TOTAL]

    } catch (e: Exception) {
        // Now this catch block only handles actual runtime exceptions,
        // rather than Errors from missing methods.
    }
}

उपयोगकर्ता के डिवाइस पर कदमों की गिनती करने की सुविधा

  • सेंसर का इस्तेमाल: Health Connect, SensorManager के TYPE_STEP_COUNTER सेंसर का इस्तेमाल करता है. इस सेंसर को कम बैटरी खर्च करने के लिए ऑप्टिमाइज़ किया गया है. इसलिए, यह बैकग्राउंड में लगातार कदमों को ट्रैक करने के लिए सबसे सही है.
  • डेटा की बारीकी से जांच करना: बैटरी लाइफ़ को बचाने के लिए, कदमों की जानकारी को आम तौर पर बैच किया जाता है. साथ ही, इसे Health Connect के डेटाबेस में हर मिनट में एक बार से ज़्यादा नहीं लिखा जाता.
  • एट्रिब्यूशन: इस सुविधा से जून 2026 से पहले रिकॉर्ड किए गए चरणों को android पैकेज के नाम से एट्रिब्यूट किया जाता है. यह नाम DataOrigin में दिखता है. इस तारीख के बाद, उन्हें डिवाइस के हिसाब से एसपीएन एट्रिब्यूट किया जाता है. उपयोगकर्ता के डिवाइस पर किए गए चरणों के लिए एट्रिब्यूशन में बदलाव लेख पढ़ें.
  • चालू करना: उपयोगकर्ता के डिवाइस पर कदमों की गिनती करने की सुविधा सिर्फ़ तब चालू होती है, जब डिवाइस पर मौजूद किसी एक ऐप्लिकेशन को Health Connect में READ_STEPS अनुमति दी गई हो.

यह देखना कि Health Connect मौजूद और चालू है या नहीं

Health Connect का इस्तेमाल करने से पहले, आपके ऐप्लिकेशन को यह पुष्टि करनी चाहिए कि उपयोगकर्ता के डिवाइस पर Health Connect इंस्टॉल हो. ऐसा हो सकता है कि Health Connect, सभी डिवाइसों पर पहले से इंस्टॉल न हो या इसे बंद कर दिया गया हो. HealthConnectClient.getSdkStatus() का इस्तेमाल करके, यह देखा जा सकता है कि Health Connect उपलब्ध है या नहीं.

यह देखने का तरीका कि 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
}

getSdkStatus() से मिले स्टेटस के आधार पर, ज़रूरी होने पर उपयोगकर्ता को Google Play Store से Health Connect इंस्टॉल या अपडेट करने के लिए कहा जा सकता है.

ज़रूरी अनुमतियां

कदमों की जानकारी को ऐक्सेस करने के लिए, इन अनुमतियों का इस्तेमाल किया जाता है:

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

अपने ऐप्लिकेशन में कदमों की जानकारी दिखाने की सुविधा जोड़नी है, तो Steps डेटा टाइप के लिए, अनुमतियों का अनुरोध करें.

यहां उस अनुमति के बारे में बताया गया है जिसके बारे में आपको एलान करना होगा, ताकि कदमों की जानकारी में बदलाव किया जा सके:

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

कदमों की जानकारी ऐक्सेस करने के लिए, आपको ये अनुमतियां मांगनी होंगी:

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

उपयोगकर्ता से अनुमतियों का अनुरोध करना

क्लाइंट इंस्टेंस बनाने के बाद, आपके ऐप्लिकेशन को उपयोगकर्ता से अनुमतियों का अनुरोध करना होगा. उपयोगकर्ताओं के पास किसी भी समय अनुमतियां देने या अस्वीकार करने का विकल्प ज़रूर होना चाहिए. इसके लिए, ज़रूरी डेटा टाइप के लिए अनुमतियों का सेट बनाएं. पक्का करें कि सेट में मौजूद अनुमतियों का एलान, सबसे पहले आपके Android मेनिफ़ेस्ट में किया गया हो.

val permissions =
    setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )
getGrantedPermissions का इस्तेमाल करके देखें कि आपके ऐप्लिकेशन को ज़रूरी अनुमतियां पहले से मिली हुई हैं या नहीं. अगर ऐसा नहीं है, तो उन अनुमतियों का अनुरोध करने के लिए createRequestPermissionResultContract का इस्तेमाल करें. इससे Health Connect की अनुमतियों वाली स्क्रीन दिखती है.
val permissions = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class)
    )

val requestPermissionsLauncher = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { grantedPermissions ->
    if (grantedPermissions.containsAll(permissions)) {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") }
    } else {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") }
    }
}
उपयोगकर्ता किसी भी समय अनुमतियां दे या रद्द कर सकते हैं. इसलिए, आपके ऐप्लिकेशन को हर बार अनुमतियों का इस्तेमाल करने से पहले, उनकी जांच करनी होगी. साथ ही, उन स्थितियों को मैनेज करना होगा जिनमें अनुमति रद्द कर दी गई है.

कदमों के रिकॉर्ड में शामिल जानकारी

हर StepsRecord में यह जानकारी शामिल होती है:

  • count: समय के अंतराल में चले गए कदमों की संख्या, Long के तौर पर.
  • startTime: मेज़रमेंट इंटरवल शुरू होने का समय.
  • endTime: मेज़रमेंट इंटरवल खत्म होने का समय.
  • startZoneOffset: यह शुरू होने के समय के लिए ज़ोन ऑफ़सेट है.
  • endZoneOffset: यह खत्म होने के समय के लिए ज़ोन ऑफ़सेट है.

इस्तेमाल किए जा सकने वाले एग्रीगेशन

StepsRecord के लिए, ये एग्रीगेट वैल्यू उपलब्ध हैं:

StepsCadenceRecord के लिए, ये एग्रीगेट वैल्यू उपलब्ध हैं:

उदाहरण उपयोग

यहां दिए गए सेक्शन में, StepsRecord डेटा को पढ़ने और लिखने का तरीका बताया गया है.

चलते समय लिए गए कदमों का डेटा सेव करने की अनुमति दें

आपका ऐप्लिकेशन, StepsRecord इंस्टेंस डालकर, कदमों की संख्या का डेटा लिख सकता है. यहां दिए गए उदाहरण में, किसी उपयोगकर्ता के 1,000 कदम रिकॉर्ड करने का तरीका दिखाया गया है:

val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime)
val stepsRecord = StepsRecord(
    count = 120,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = zoneOffset,
    endZoneOffset = zoneOffset,
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    )
)
healthConnectClient.insertRecords(listOf(stepsRecord))

कुल डेटा पढ़ने की अनुमति दें

कदमों की जानकारी को पढ़ने का सबसे सामान्य तरीका यह है कि किसी समयावधि में कुल कदमों की संख्या को इकट्ठा किया जाए. यहां दिए गए उदाहरण में, किसी उपयोगकर्ता के लिए तय समयसीमा में कुल कदमों की संख्या पढ़ने का तरीका बताया गया है:

suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long {
    val response = healthConnectClient.aggregate(
        AggregateRequest(
            metrics = setOf(StepsRecord.COUNT_TOTAL),
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )
    return response[StepsRecord.COUNT_TOTAL] ?: 0L
}

रॉ डेटा पढ़ने की अनुमति

यहां दिए गए उदाहरण में, शुरू और खत्म होने के समय के बीच के StepsRecord डेटा को पढ़ने का तरीका बताया गया है:

val response = healthConnectClient.readRecords(
    ReadRecordsRequest(
        StepsRecord::class,
        timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
    )
)
response.records.forEach { record ->
    /* Process records */
}