रॉ डेटा पढ़ें

यहां दिए गए उदाहरण में, सामान्य वर्कफ़्लो के तहत रॉ डेटा को पढ़ने का तरीका बताया गया है.

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

Health Connect, ऐप्लिकेशन को डेटास्टोर से डेटा पढ़ने की अनुमति देता है. ऐसा तब होता है, जब ऐप्लिकेशन फ़ोरग्राउंड और बैकग्राउंड में काम कर रहा हो:

  • फ़ोरग्राउंड में डेटा ऐक्सेस करना: आम तौर पर, Health Connect से डेटा तब ऐक्सेस किया जा सकता है, जब आपका ऐप्लिकेशन फ़ोरग्राउंड में हो. ऐसे मामलों में, इस ऑपरेशन को चलाने के लिए फ़ोरग्राउंड सेवा का इस्तेमाल किया जा सकता है. ऐसा तब करें, जब उपयोगकर्ता या सिस्टम, पढ़ने के ऑपरेशन के दौरान आपके ऐप्लिकेशन को बैकग्राउंड में रख दे.

  • बैकग्राउंड में डेटा ऐक्सेस करना: उपयोगकर्ता से अतिरिक्त अनुमति का अनुरोध करके, उपयोगकर्ता या सिस्टम के आपके ऐप्लिकेशन को बैकग्राउंड में रखने के बाद भी डेटा ऐक्सेस किया जा सकता है. बैकग्राउंड में डेटा पढ़ने का पूरा उदाहरण देखें.

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

रिकॉर्ड पढ़ने के लिए, ReadRecordsRequest बनाएं और readRecords को कॉल करते समय इसे उपलब्ध कराएं.

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

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

aggregate का इस्तेमाल करके, अपने डेटा को इकट्ठा किए गए फ़ॉर्मैट में भी पढ़ा जा सकता है.

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)
            )
        )
        // 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
    }
}

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

Android 14 (एपीआई लेवल 34) और SDK एक्सटेंशन के 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

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

अगर आपके ऐप्लिकेशन को डिवाइस पर मौजूद कदमों की जानकारी को पढ़ने की ज़रूरत है या वह सोर्स ऐप्लिकेशन या डिवाइस के हिसाब से कदमों की जानकारी दिखाता है, तो उन रिकॉर्ड के लिए क्वेरी की जा सकती है जिनमें DataOrigin android है. अगर आपका ऐप्लिकेशन, स्टेप डेटा के लिए एट्रिब्यूशन दिखाता है, तो आपको Android पैकेज से मिले डेटा को मौजूदा डिवाइस के लिए एट्रिब्यूट करना चाहिए. इसके लिए, "आपका फ़ोन" जैसे लेबल का इस्तेमाल करें. इसके अलावा, Settings.Global.getString(resolver, Settings.Global.DEVICE_NAME) की मदद से डिवाइस का नाम पाएं या रिकॉर्ड के मेटाडेटा में मौजूद Device फ़ील्ड की जांच करें.

नीचे दिए गए उदाहरण में, 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
    }
}

ऑन-डिवाइस स्टेप काउंटिंग

डिवाइस पर ही कदमों की गिनती करने की सुविधा के बारे में ज़्यादा जानकारी:

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

बैकग्राउंड में पढ़ने की सुविधा का उदाहरण

बैकग्राउंड में डेटा पढ़ने के लिए, अपनी मेनिफ़ेस्ट फ़ाइल में यह अनुमति दें:

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

यहां दिए गए उदाहरण में, WorkManager का इस्तेमाल करके, किसी उपयोगकर्ता के लिए एक तय समय में, बैकग्राउंड में कदमों की संख्या का डेटा पढ़ने का तरीका दिखाया गया है:

class ScheduleWorker(private val appContext: Context, workerParams: WorkerParameters):
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        // Read data and process it.
        ...

        // Return success indicating successful data retrieval
        return Result.success()
    }
}

if (healthConnectClient
    .features
    .getFeatureStatus(
    HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
    ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

    // Check if necessary permission is granted
    val grantedPermissions = healthConnectClient.permissionController.getGrantedPermissions()

    if (PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND !in grantedPermissions) {
        // Perform read in foreground
        ...
    } else {
        // Schedule the periodic work request in background
        val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
            .build()

        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            periodicWorkRequest
        )
    }
} else {
  // Background reading is not available, perform read in foreground
  ...
}

ReadRecordsRequest पैरामीटर की डिफ़ॉल्ट pageSize वैल्यू 1000 होती है. अगर किसी एक readResponse में मौजूद रिकॉर्ड की संख्या, अनुरोध के pageSize से ज़्यादा है, तो आपको pageToken का इस्तेमाल करके, सभी रिकॉर्ड पाने के लिए जवाब के सभी पेजों पर दोहराना होगा. हालांकि, दर सीमित करने से जुड़ी समस्याओं से बचने के लिए सावधानी बरतें.

pageToken पढ़ने का उदाहरण

हमारा सुझाव है कि रिकॉर्ड पढ़ने के लिए pageToken का इस्तेमाल करें, ताकि अनुरोध की गई समयावधि का सारा उपलब्ध डेटा वापस पाया जा सके.

यहां दिए गए उदाहरण में, सभी पेज टोकन खत्म होने तक सभी रिकॉर्ड पढ़ने का तरीका बताया गया है:

val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))

try {
    var pageToken: String? = null
    do {
        val readResponse =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    recordType = type,
                    timeRangeFilter = TimeRangeFilter.between(
                        startTime,
                        endTime
                    ),
                    pageToken = pageToken
                )
            )
        val records = readResponse.records
        // Do something with records
        pageToken = readResponse.pageToken
    } while (pageToken != null)
} catch (quotaError: IllegalStateException) {
    // Backoff
}

बड़े डेटासेट को पढ़ने के सबसे सही तरीकों के बारे में जानने के लिए, रेट लिमिट से बचने के लिए प्लान बनाना लेख पढ़ें.

पहले से लिखे गए डेटा को पढ़ना

अगर किसी ऐप्लिकेशन ने Health Connect में पहले से रिकॉर्ड सेव किए हैं, तो वह ऐप्लिकेशन पुराना डेटा ऐक्सेस कर सकता है. यह उन स्थितियों पर लागू होता है जिनमें उपयोगकर्ता के ऐप्लिकेशन को फिर से इंस्टॉल करने के बाद, उसे Health Connect के साथ फिर से सिंक करना होता है.

पढ़ने से जुड़ी कुछ पाबंदियां लागू होती हैं:

  • Android 14 और इसके बाद के वर्शन के लिए

    • कोई ऐप्लिकेशन अपने डेटा को पढ़ सकता है. इसके लिए, कोई समयसीमा तय नहीं की गई है.
    • कोई ऐप्लिकेशन, दूसरे ऐप्लिकेशन का डेटा 30 दिनों तक पढ़ सकता है.
  • Android 13 और इससे पुराने वर्शन के लिए

    • ऐप्लिकेशन को किसी भी डेटा को ऐक्सेस करने की अनुमति सिर्फ़ 30 दिनों के लिए होती है.

पढ़ने की अनुमति का अनुरोध करके, पाबंदियां हटाई जा सकती हैं.

पुराना डेटा पढ़ने के लिए, आपको ReadRecordsRequest के dataOriginFilter पैरामीटर में पैकेज का नाम, DataOrigin ऑब्जेक्ट के तौर पर दिखाना होगा.

यहां दिए गए उदाहरण में, हार्ट रेट के रिकॉर्ड पढ़ते समय पैकेज का नाम बताने का तरीका दिखाया गया है:

try {
    val response =  healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
            dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
        )
    )
    for (record in response.records) {
        // Process each record
    }
} catch (e: Exception) {
    // Run error handling here
}

30 दिन से ज़्यादा पुराना डेटा पढ़ना

डिफ़ॉल्ट रूप से, सभी ऐप्लिकेशन को Health Connect से 30 दिन पहले तक का डेटा ऐक्सेस करने की अनुमति होती है. यह अवधि, अनुमति मिलने की तारीख से शुरू होती है.

अगर आपको डिफ़ॉल्ट पाबंदियों के अलावा, पढ़ने की अनुमतियों को बढ़ाना है, तो PERMISSION_READ_HEALTH_DATA_HISTORY का अनुरोध करें. इसके अलावा, इस अनुमति के बिना 30 दिन से ज़्यादा पुरानी रिकॉर्डिंग को पढ़ने की कोशिश करने पर गड़बड़ी होती है.

मिटाए गए ऐप्लिकेशन के लिए अनुमतियों का इतिहास

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

उदाहरण के लिए, मान लें कि उपयोगकर्ता ने 10 मई, 2023 को आपका ऐप्लिकेशन मिटा दिया. इसके बाद, उसने 15 मई, 2023 को ऐप्लिकेशन को फिर से इंस्टॉल किया और पढ़ने की अनुमतियां दीं. आपका ऐप्लिकेशन अब डिफ़ॉल्ट रूप से, 15 अप्रैल, 2023 से डेटा पढ़ सकता है.

अपवादों को मैनेज करना

समस्या आने पर, Health Connect, CRUD ऑपरेशनों के लिए स्टैंडर्ड अपवाद दिखाता है. आपका ऐप्लिकेशन, इनमें से हर अपवाद को सही तरीके से पकड़ना और हैंडल करना चाहिए.

HealthConnectClient में मौजूद हर तरीके में, उन अपवादों की सूची दी गई होती है जो थ्रो किए जा सकते हैं. आम तौर पर, आपके ऐप्लिकेशन को इन अपवादों को हैंडल करना चाहिए:

टेबल 1: Health Connect के अपवाद और सबसे सही तरीके
अपवाद ब्यौरा सुझाया गया सबसे सही तरीका
IllegalStateException इनमें से कोई एक स्थिति हुई है:

  • Health Connect सेवा उपलब्ध नहीं है.
  • अनुरोध मान्य नहीं है. उदाहरण के लिए, समय-समय पर बकेट में एग्रीगेट करने का अनुरोध, जिसमें timeRangeFilter के लिए Instant ऑब्जेक्ट का इस्तेमाल किया जाता है.

अनुरोध करने से पहले, इनपुट से जुड़ी संभावित समस्याओं को ठीक करें. हमारा सुझाव है कि आप वैरिएबल को वैल्यू असाइन करें या उन्हें कस्टम फ़ंक्शन में पैरामीटर के तौर पर इस्तेमाल करें. ऐसा करने से, आपको अनुरोधों में सीधे तौर पर वैरिएबल का इस्तेमाल नहीं करना पड़ेगा. इससे आपको गड़बड़ी ठीक करने की रणनीतियां लागू करने में मदद मिलेगी.
IOException डिस्क से डेटा पढ़ने और लिखने के दौरान समस्याएं आती हैं. इस समस्या से बचने के लिए, यहां कुछ सुझाव दिए गए हैं:

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

RemoteException SDK जिस सेवा से कनेक्ट होता है उसमें या उससे कम्यूनिकेट करने में गड़बड़ियां हुई हैं.

उदाहरण के लिए, आपका ऐप्लिकेशन दिए गए uid के साथ किसी रिकॉर्ड को मिटाने की कोशिश कर रहा है. हालांकि, ऐप्लिकेशन को यह अपवाद तब मिलता है, जब वह यह पता लगा लेता है कि रिकॉर्ड मौजूद नहीं है. इसके लिए, वह बुनियादी सेवा में चेक इन करता है.
इस समस्या से बचने के लिए, यहां कुछ सुझाव दिए गए हैं:

  • अपने ऐप्लिकेशन के डेटास्टोर और Health Connect के बीच नियमित रूप से डेटा सिंक करें.
  • अनुरोध से जुड़ी समस्याओं को हल करने के लिए, फिर से कोशिश करने और बैकऑफ़ की रणनीतियों को लागू करें.

SecurityException जब अनुरोधों के लिए ऐसी अनुमतियों की ज़रूरत होती है जो नहीं दी गई हैं, तब समस्याएं आती हैं. इससे बचने के लिए, पक्का करें कि आपने पब्लिश किए गए ऐप्लिकेशन के लिए, Health Connect के डेटा टाइप के इस्तेमाल के बारे में एलान किया हो. साथ ही, आपको मेनिफ़ेस्ट फ़ाइल में और अपनी गतिविधि में, Health Connect की अनुमतियों के बारे में एलान करना होगा.