बैकग्राउंड में डेटा की निगरानी करें

पैसिव डेटा अपडेट, उन ऐप्लिकेशन के लिए सही हैं जिन्हें स्वास्थ्य सेवाओं को मॉनिटर करने की ज़रूरत होती है बैकग्राउंड में डेटा मिल जाता है. वे उन मामलों के लिए हैं जो घंटे, दिन या और लंबे समय तक काम करता है. अगर आपको ऐप्लिकेशन में सेहत से जुड़ा डेटा सेव या प्रोसेस करने की ज़रूरत पड़ती है नहीं चल रहा है और उपयोगकर्ता स्पष्ट रूप से किसी व्यायाम में शामिल नहीं है, तो हेल्थ सर्विस का पैसिव क्लाइंट.

पैसिव डेटा खर्च के उदाहरणों के लिए, पैसिव डेटा और पैसिव लक्ष्य GitHub पर सैंपल.

डिपेंडेंसी जोड़ें

Health Services पर डिपेंडेंसी जोड़ने के लिए, आपको Google Maven रिपॉज़िटरी जोड़ना होगा को भी शामिल किया जा सकता है. ज़्यादा जानकारी के लिए, यह देखें Google की Maven रिपॉज़िटरी.

अपने मॉड्यूल-लेवल की build.gradle फ़ाइल में, यह डिपेंडेंसी जोड़ें:

Groovy

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

Kotlin

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

सुविधाएं देखें

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

val healthClient = HealthServices.getClient(this /*context*/)
val passiveMonitoringClient = healthClient.passiveMonitoringClient
lifecycleScope.launchWhenCreated {
    val capabilities = passiveMonitoringClient.capabilities.await()
    // Supported types for passive data collection
    supportsHeartRate =
        DataType.HEART_RATE_BPM in capabilities.supportedDataTypesPassiveMonitoring
    // Supported types for PassiveGoals
    supportsStepsGoal =
        DataType.STEPS_DAILY in capabilities.supportedDataTypesPassiveGoals
}

पैसिव डेटा के लिए रजिस्टर करें

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

आप चाहे कोई भी तरीका इस्तेमाल करें, पहले PassiveListenerConfig बनाएं जो तय करता है कि किस तरह का डेटा मिलना चाहिए, जैसा कि इस उदाहरण में दिखाया गया है:

val passiveListenerConfig = PassiveListenerConfig.builder()
    .setDataTypes(setOf(DataType.HEART_RATE_BPM))
    .build()

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

val passiveListenerCallback: PassiveListenerCallback = object : PassiveListenerCallback {
    override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
        // TODO: Do something with dataPoints
    }
}

passiveMonitoringClient.setPassiveListenerCallback(
    passiveListenerConfig,
    passiveListenerCallback
)

// To remove the listener
passiveMonitoringClient.clearPassiveListenerCallbackAsync()

किसी सेवा का उपयोग करना समान है, लेकिन वह इससे प्राप्त की गई क्लास बनाने के बजाय PassiveListenerCallback, PassiveListenerService से लिया गया है, जैसा कि यहां दिखाया गया है नीचे दिया गया उदाहरण:

class PassiveDataService : PassiveListenerService() {
    override fun onNewDataPointsReceived(dataPoints: DataPointContainer) {
        // TODO: Do something with dataPoints
    }
}

passiveMonitoringClient.setPassiveListenerServiceAsync(
    PassiveDataService::class.java,
    passiveListenerConfig
)

इसके बाद, अपनी AndroidManifest.xml फ़ाइल में सेवा के बारे में बताएं. स्वास्थ्य से जुड़ी ज़रूरी जानकारी सेवाओं की अनुमति, जिससे यह पक्का होता है कि सिर्फ़ स्वास्थ्य सेवाएं ही शर्तों को पूरा कर सकती हैं सेवा को:

<service android:name=".PassiveDataService"
    android:permission="com.google.android.wearable.healthservices.permission.PASSIVE_DATA_BINDING"
    android:exported="true" />

समय की जानकारी दें

Health Services से मिलने वाले डेटा को बैच में भेजा जाता है. इससे आपको यह डेटा मिल सकता है अलग-अलग तरह के पॉइंट या एक ही तरह के एक से ज़्यादा डेटा पॉइंट, बैच. समय के बजाय इन ऑब्जेक्ट में शामिल टाइमस्टैंप का इस्तेमाल करें ये इवेंट आपके ऐप्लिकेशन को मिले हों, ताकि इवेंट के सही क्रम का पता लगाया जा सके.

पहले बूट टाइमस्टैंप का हिसाब लगाकर, हर DataPoint के लिए टाइमस्टैंप पाएं, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:

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

इसके बाद, यह वैल्यू इन्हें भेजी जा सकती है getStartInstant() या getEndInstant().

बूट के बाद रजिस्ट्रेशन वापस लाना

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

रिसीवर में, रजिस्ट्रेशन को सीधे तौर पर वापस लाने की कोशिश न करें. इसके बजाय, यह सुविधा WorkManager वर्कर को सौंपी जाती है. जब डिवाइस चालू हो रहा है, तो Health Services को मिलने में 10 सेकंड या उससे ज़्यादा समय लग सकता है पैसिव डेटा रजिस्ट्रेशन अनुरोध स्वीकार करते हैं. साथ ही, इस प्रक्रिया के तहत BroadcastReceiver को लागू करने का उचित समय. इसके उलट, WorkManager कर्मचारियों के पास 10 मिनट तक प्रोग्राम चलाने की सीमा.

नीचे दिया गया स्निपेट दिखाता है कि BroadcastReceiver कैसा दिख सकता है:

class StartupReceiver : BroadcastReceiver() {

   override fun onReceive(context: Context, intent: Intent) {
       if (intent.action != Intent.ACTION_BOOT_COMPLETED) return


       // TODO: Check permissions first
       WorkManager.getInstance(context).enqueue(
           OneTimeWorkRequestBuilder<RegisterForPassiveDataWorker>().build()
       )
   }
}

class RegisterForPassiveDataWorker(
   private val appContext: Context,
   workerParams: WorkerParameters
) : Worker(appContext, workerParams) {

   override fun doWork(): Result {
       runBlocking {
           HealthServices.getClient(appContext)
                .passiveMonitoringClient
                .setPassiveListenerCallback(...)
       }
       return Result.success()
   }
}

डिवाइस के बूट होने पर सिस्टम इस कोड को चलाए, इसके लिए AndroidManifest.xml फ़ाइल में दो बदलाव किए गए हैं.

सबसे पहले, <manifest> के बच्चे के तौर पर यह अनुमति जोड़ें:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

इसके बाद, <application> के चाइल्ड के तौर पर यह रिसीवर इंटेंट फ़िल्टर जोड़ें:

<receiver
    android:name=".StartupReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

गतिविधि की स्थिति

पैसिव क्लाइंट, उपयोगकर्ता की स्थिति के बारे में ज़्यादा जानकारी भी दे सकता है, जैसे जैसे कि उपयोगकर्ता सो रहा है. ये अपडेट पाने के लिए, यह तरीका अपनाएं:

  1. ACTIVITY_RECOGNITION की अनुमति का अनुरोध करें.
  2. इतने समय में setShouldUserActivityInfoBeRequested(true) को कॉल करें: PassiveListenerConfig बिल्डर.

अपने कॉलबैक या सेवा में onUserActivityInfoReceived() तरीके को बदलें और लौटाए गए UserActivityInfo का इस्तेमाल करें, जैसा कि इस उदाहरण में दिखाया गया है:

override fun onUserActivityInfoReceived(info: UserActivityInfo) {
    val stateChangeTime: Instant = info.stateChangeTime // may be in the past!
    val userActivityState: UserActivityState = info.userActivityState
    if (userActivityState == UserActivityState.USER_ACTIVITY_ASLEEP) {
        // ...
    }
}

पैसिव लक्ष्य

पैसिव क्लाइंट को कॉन्फ़िगर किया जा सकता है, ताकि जब पैसिव गोल हो जाएं, तब ऐप्लिकेशन को इसकी सूचना दी जा सके लक्ष्य हासिल हो जाते हैं, जैसे कि उपयोगकर्ता एक दिन में 10,000 कदम पूरे कर लेता है.

ऐसा करने के लिए, एक लक्ष्य बनाएं, जैसा कि इस उदाहरण में दिखाया गया है:

val dailyStepsGoal by lazy {
    val condition = DataTypeCondition(
        dataType = DataType.STEPS_DAILY,
        threshold = 10_000, // Trigger every 10000 steps
        comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
    )
    PassiveGoal(condition)
}

इस लक्ष्य को अपने PassiveListenerConfig में जोड़ें, जैसा कि यहां दिखाया गया है उदाहरण:

val passiveListenerConfig = PassiveListenerConfig.builder()
    .setDailyGoals(setOf(dailyStepsGoal))
    .build()

अपने कॉलबैक या सेवा में onGoalCompleted() तरीके को बदलें और लौटाए गए PassiveGoal का इस्तेमाल करें, जैसा कि इस उदाहरण में दिखाया गया है:

override fun onGoalCompleted(goal: PassiveGoal) {
    when (goal.dataTypeCondition.dataType) {
        DataType.STEPS_DAILY -> {
            // ...
        }
    }
}