Wear OS मॉड्यूल को इंटिग्रेट करना

पहने जाने वाले ऐप्लिकेशन की सुविधाओं का इस्तेमाल करके, अपनी सेहत और फ़िटनेस से जुड़ा बेहतर अनुभव पाएं Wear OS वाले डिवाइसों पर.

Wear OS मॉड्यूल जोड़ें

Android Studio एक आसान विज़र्ड है, जिसकी मदद से अपने ऐप्लिकेशन में Wear OS मॉड्यूल जोड़ा जा सकता है. तय सीमा में फ़ाइल > नया मॉड्यूल मेन्यू में, Wear OS चुनें, जैसा कि यहां दिखाया गया है इमेज:

Android Studio में Wear OS मॉड्यूल का विज़र्ड
पहली इमेज: Wear OS मॉड्यूल बनाना

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

विज़र्ड पूरा करने के बाद, अपने प्रोजेक्ट को सिंक करें. नीचे दिया गया Run कॉन्फ़िगरेशन दिखाई देता है:

Wear OS ऐप्लिकेशन का रन बटन दिखाने वाली इमेज
दूसरी इमेज: नए Wear OS मॉड्यूल के लिए 'रन बटन'

इससे, पहने जाने वाले डिवाइस पर Wear OS मॉड्यूल चलाया जा सकता है. आपके पास दो विकल्प हैं:

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

स्वास्थ्य सेवाएं और हिल्ट जोड़ें

अपने Wear OS मॉड्यूल में इन लाइब्रेरी को इंटिग्रेट करें:

  • स्वास्थ्य सेवाएं: स्मार्ट वॉच के सेंसर और डेटा को ऐक्सेस करने की सुविधा देती हैं ये डिवाइस आसानी से इस्तेमाल किए जा सकते हैं और बिजली की कम खपत करते हैं.
  • Hilt: यह असरदार तरीके से डिपेंडेंसी इंजेक्शन और मैनेज करने की सुविधा देता है.

हेल्थ सर्विसेज़ मैनेजर बनाएं

स्वास्थ्य सेवाओं को आसानी से इस्तेमाल करना और ज़्यादा आसान बनाना और बेहतर एपीआई, तो आप इस तरह का रैपर बना सकते हैं:

private const val TAG = "WATCHMAIN"

class HealthServicesManager(context: Context) {
    private val measureClient = HealthServices.getClient(context).measureClient

    suspend fun hasHeartRateCapability() = runCatching {
        val capabilities = measureClient.getCapabilities()
        (DataType.HEART_RATE_BPM in capabilities.supportedDataTypesMeasure)
    }.getOrDefault(false)

    /**
     * Returns a cold flow. When activated, the flow will register a callback for heart rate data
     * and start to emit messages. When the consuming coroutine is canceled, the measure callback
     * is unregistered.
     *
     * [callbackFlow] creates a  bridge between a callback-based API and Kotlin flows.
     */
    @ExperimentalCoroutinesApi
    fun heartRateMeasureFlow(): Flow<MeasureMessage> = callbackFlow {
        val callback = object : MeasureCallback {
            override fun onAvailabilityChanged(dataType: DeltaDataType<*, *>, availability: Availability) {
                // Only send back DataTypeAvailability (not LocationAvailability)
                if (availability is DataTypeAvailability) {
                    trySendBlocking(MeasureMessage.MeasureAvailability(availability))
                }
            }

            override fun onDataReceived(data: DataPointContainer) {
                val heartRateBpm = data.getData(DataType.HEART_RATE_BPM)
                Log.d(TAG, "💓 Received heart rate: ${heartRateBpm.first().value}")
                trySendBlocking(MeasureMessage.MeasureData(heartRateBpm))
            }
        }

        Log.d(TAG, "⌛ Registering for data...")
        measureClient.registerMeasureCallback(DataType.HEART_RATE_BPM, callback)

        awaitClose {
            Log.d(TAG, "👋 Unregistering for data")
            runBlocking {
                measureClient.unregisterMeasureCallback(DataType.HEART_RATE_BPM, callback)
            }
        }
    }
}

sealed class MeasureMessage {
    class MeasureAvailability(val availability: DataTypeAvailability) : MeasureMessage()
    class MeasureData(val data: List<SampleDataPoint<Double>>) : MeasureMessage()
}

नीचे दिए गए स्निपेट का इस्तेमाल करके, Hilt मॉड्यूल को मैनेज करने के लिए इसे बनाने के बाद:

@Module
@InstallIn(SingletonComponent::class)
internal object DataModule {
    @Provides
    @Singleton
    fun provideHealthServices(@ApplicationContext context: Context): HealthServicesManager = HealthServicesManager(context)
}

आपके पास HealthServicesManager को Hilt की अन्य डिपेंडेंसी के तौर पर इंजेक्ट करने का विकल्प है.

नए HealthServicesManager में heartRateMeasureFlow() तरीका मिलता है, हार्ट मॉनिटर के लिए लिसनर रजिस्टर करता है और मिले डेटा को इकट्ठा करता है.

पहने जाने वाले डिवाइसों पर डेटा अपडेट करने की सुविधा चालू करें

फ़िटनेस से जुड़े डेटा को अपडेट करने के लिए, BODY_SENSORS की अनुमति की ज़रूरत होती है. अगर आपको अभी तक ऐसा नहीं किया है, तो अपनी साइट में BODY_SENSORS अनुमति का एलान करें की मेनिफ़ेस्ट फ़ाइल में दी गई है. इसके बाद, अनुमति का अनुरोध करें, जैसा कि इस स्निपेट में दिखाया गया है:

val permissionState = rememberPermissionState(
    permission = Manifest.permission.BODY_SENSORS,
    onPermissionResult = { granted -> /* do something */ }
)

[...]

if (permissionState.status.isGranted) {
    // do something
} else {
    permissionState.launchPermissionRequest()
}

अगर किसी डिवाइस पर अपने ऐप्लिकेशन की जांच की जाती है, तो डेटा अपडेट होना शुरू हो जाना चाहिए.

Wear OS 4 में शुरू होने वाले एम्युलेटर, टेस्ट डेटा को अपने-आप भी दिखाते हैं. पिछले पर वर्शन हैं, तो सेंसर से डेटा स्ट्रीम को सिम्युलेट किया जा सकता है. टर्मिनल में विंडो में, इस ADB कमांड को चलाएं:

adb shell am broadcast \
-a "whs.USE_SYNTHETIC_PROVIDERS" \
com.google.android.wearable.healthservices

धड़कन की दर के अलग-अलग मान देखने के लिए, अलग-अलग कसरतों को सिम्युलेट करें. यह निर्देश, पैदल चलने के बारे में बताता है:

adb shell am broadcast \
-a "whs.synthetic.user.START_WALKING" \
com.google.android.wearable.healthservices

इस निर्देश से, दौड़ने के बारे में जानकारी मिलती है:

adb shell am broadcast \
-a "whs.synthetic.user.START_RUNNING" \
com.google.android.wearable.healthservices

डेटा को सिम्युलेट करना बंद करने के लिए, इस निर्देश को चलाएं:

adb shell am broadcast -a \
"whs.USE_SENSOR_PROVIDERS" \
com.google.android.wearable.healthservices

धड़कन की दर का डेटा पढ़ें

BODY_SENSORS की अनुमति मिलने के बाद, लोगों के दिल की धड़कन की दर देखी जा सकती है HealthServicesManager में (heartRateMeasureFlow()). Wear OS ऐप्लिकेशन में यूज़र इंटरफ़ेस (यूआई) में, धड़कन की मौजूदा दर की वैल्यू दिखती है. इसे पहने जाने वाला डिवाइस.

अपने ViewModel में, धड़कन की दर के फ़्लो से जुड़े ऑब्जेक्ट का इस्तेमाल करके डेटा इकट्ठा करना शुरू करें, जैसा कि नीचे दिए गए स्निपेट में दिखाया गया है:

val hr: MutableState<Double> = mutableStateOf(0.0)

[...]

healthServicesManager
    .heartRateMeasureFlow()
    .takeWhile { enabled.value }
    .collect { measureMessage ->
        when (measureMessage) {
            is MeasureData -> {
                val latestHeartRateValue = measureMessage.data.last().value
                hr.value = latestHeartRateValue
            }

            is MeasureAvailability -> availability.value =
                    measureMessage.availability
        }
    }

लाइव डेटा दिखाने के लिए, नीचे दिए गए ऑब्जेक्ट से मिलते-जुलते कंपोज़ेबल ऑब्जेक्ट का इस्तेमाल करें अपने ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई):

val heartRate by viewModel.hr

Text(
  text = "Heart Rate: $heartRate",
  style = MaterialTheme.typography.display1
)

हैंडहेल्ड डिवाइस पर डेटा भेजें

हैंडहेल्ड डिवाइस पर सेहत और फ़िटनेस का डेटा भेजने के लिए, DataClient का इस्तेमाल करें स्वास्थ्य सेवाओं की क्लास में शामिल होते हैं. नीचे दिया गया कोड स्निपेट दिल का निशान भेजने का तरीका बताता है आपके ऐप्लिकेशन ने जो डेटा इकट्ठा किया है उसे रेटिंग दें:

class HealthServicesManager(context: Context) {
    private val dataClient by lazy { Wearable.getDataClient(context) }

[...]

    suspend fun sendToHandheldDevice(heartRate: Int) {
        try {
            val result = dataClient
                .putDataItem(PutDataMapRequest
                    .create("/heartrate")
                    .apply { dataMap.putInt("heartrate", heartRate) }
                    .asPutDataRequest()
                    .setUrgent())
                .await()

            Log.d(TAG, "DataItem saved: $result")
        } catch (cancellationException: CancellationException) {
            throw cancellationException
        } catch (exception: Exception) {
            Log.d(TAG, "Saving DataItem failed: $exception")
        }
    }
}

फ़ोन पर डेटा पाएं

फ़ोन पर डेटा पाने के लिए, WearableListenerService:

@AndroidEntryPoint
class DataLayerListenerService : WearableListenerService() {

    @Inject
    lateinit var heartRateMonitor: HeartRateMonitor

    override fun onDataChanged(dataEvents: DataEventBuffer) {

        dataEvents.forEach { event ->
            when (event.type) {
                DataEvent.TYPE_CHANGED -> {
                    event.dataItem.run {
                        if (uri.path?.compareTo("/heartrate") == 0) {
                            val heartRate = DataMapItem.fromDataItem(this)
                                    .dataMap.getInt(HR_KEY)
                            Log.d("DataLayerListenerService",
                                    "New heart rate value received: $heartRate")
                            heartRateMonitor.send(heartRate)
                        }
                    }
                }

                DataEvent.TYPE_DELETED -> {
                    // DataItem deleted
                }
            }
        }
    }
}

यह चरण पूरा करने के बाद, कुछ दिलचस्प जानकारी देखें:

  • @AndroidEntryPoint एनोटेशन से हम इस क्लास में Hilt का इस्तेमाल कर पाते हैं
  • @Inject lateinit var heartRateMonitor: HeartRateMonitor यह काम करेगा इस क्लास में डिपेंडेंसी इंजेक्ट करें
  • क्लास, onDataChanged() को लागू करती है और इसे इवेंट का एक कलेक्शन मिलता है तो आप पार्स कर सकते हैं और

यहां दिए गए HeartRateMonitor लॉजिक की मदद से, धड़कन की दर के डेटा की जानकारी भेजी जा सकती है आपके ऐप्लिकेशन के कोड बेस के किसी दूसरे हिस्से में वैल्यू होनी चाहिए:

class HeartRateMonitor {
    private val datapoints = MutableSharedFlow<Int>(extraBufferCapacity = 10)

    fun receive(): SharedFlow<Int> = datapoints.asSharedFlow()

    fun send(hr: Int) {
        datapoints.tryEmit(hr)
    }
}

डेटा बस को onDataChanged() तरीके से इवेंट मिलते हैं और वे उन्हें बनाती हैं एक SharedFlow का इस्तेमाल करके डेटा ऑब्ज़र्वर के लिए उपलब्ध है.

आखिरी बिट, फ़ोन ऐप्लिकेशन में Service के बारे में जानकारी देना है AndroidManifest.xml:

<service
    android:name=".DataLayerListenerService"
    android:exported="true">
    <intent-filter>
        <!-- listeners receive events that match the action and data filters -->
        <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
        <data
            android:host="*"
            android:pathPrefix="/heartrate"
            android:scheme="wear" />
    </intent-filter>
</service>

हैंडहेल्ड डिवाइस पर रीयल-टाइम डेटा दिखाएं

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