Wear पर डेटा लेयर इवेंट मैनेज करना

Data Layer API को कॉल करने पर, कॉल पूरा होने के बाद आपको कॉल का स्टेटस मिल सकता है. इसके अलावा, Wear OS by Google नेटवर्क पर कहीं भी आपके ऐप्लिकेशन के डेटा में हुए बदलावों से जुड़े डेटा इवेंट भी सुने जा सकते हैं.

डेटा लेयर एपीआई का असरदार तरीके से इस्तेमाल करने का उदाहरण देखने के लिए, Android DataLayer Sample ऐप्लिकेशन देखें.

डेटा लेयर कॉल के स्टेटस का इंतज़ार करना

डेटा लेयर एपीआई को किए गए कॉल, जैसे कि DataClient क्लास के putDataItem तरीके का इस्तेमाल करके किया गया कॉल, कभी-कभी Task<ResultType> ऑब्जेक्ट दिखाता है. Task ऑब्जेक्ट के बनते ही, ऑपरेशन को बैकग्राउंड में कतार में लगा दिया जाता है. इसके बाद, कोई कार्रवाई न करने पर यह प्रोसेस अपने-आप पूरी हो जाती है.

हालांकि, आम तौर पर ऑपरेशन पूरा होने के बाद, आपको नतीजे के साथ कुछ करना होता है. इसलिए, Task ऑब्जेक्ट की मदद से, नतीजे की स्थिति का इंतज़ार किया जा सकता है. ऐसा एसिंक्रोनस या सिंक्रोनस तरीके से किया जा सकता है.

एसिंक्रोनस कॉल

अगर आपका कोड मुख्य यूज़र इंटरफ़ेस (यूआई) थ्रेड पर चल रहा है, तो डेटा लेयर एपीआई को ब्लॉक करने वाले कॉल न करें. Task ऑब्जेक्ट में कॉलबैक तरीका जोड़कर, कॉल को एसिंक्रोनस रूप से चलाएं. यह तरीका, कार्रवाई पूरी होने पर ट्रिगर होता है:

// Using Kotlin function references
task.addOnSuccessListener(::handleDataItem)
task.addOnFailureListener(::handleDataItemError)
task.addOnCompleteListener(::handleTaskComplete)
...
fun handleDataItem(dataItem: DataItem) { ... }
fun handleDataItemError(exception: Exception) { ... }
fun handleTaskComplete(task: Task<DataItem>) { ... }

अलग-अलग टास्क को एक साथ चलाने के साथ-साथ अन्य विकल्पों के बारे में जानने के लिए, Task API देखें.

सिंक्रोनस कॉल

अगर आपका कोड बैकग्राउंड सेवा में अलग हैंडलर थ्रेड पर चल रहा है, जैसे कि WearableListenerService में, तो कॉल को ब्लॉक करना ठीक है. इस मामले में, Task ऑब्जेक्ट पर Tasks.await() को कॉल किया जा सकता है. यह अनुरोध पूरा होने तक ब्लॉक रहता है और Result ऑब्जेक्ट दिखाता है. यह उदाहरण में दिखाया गया है.

ध्यान दें: मुख्य थ्रेड पर रहते हुए इसे कॉल न करें.

try {
    Tasks.await(dataItemTask).apply {
        Log.d(TAG, "Data item set: $uri")
    }
}
catch (e: ExecutionException) { ... }
catch (e: InterruptedException) { ... }

डेटा लेयर के इवेंट को मॉनिटर करना

डेटा लेयर, हैंडहेल्ड और पहनने योग्य डिवाइसों के बीच डेटा को सिंक करती है और भेजती है. इसलिए, आपको आम तौर पर डेटा आइटम के बनाए जाने और मैसेज के मिलने जैसे ज़रूरी इवेंट को सुनना होता है.

डेटा लेयर के इवेंट को मॉनिटर करने के लिए, आपके पास ये दो विकल्प हैं:

इन दोनों विकल्पों की मदद से, उन इवेंट के लिए डेटा इवेंट कॉलबैक के तरीकों को बदला जा सकता है जिन्हें आपको मैनेज करना है.

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

WearableListenerService का इस्तेमाल करना

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

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

WearableListenerService का इस्तेमाल करके, इन इवेंट को सुना जा सकता है:

  • onDataChanged(): जब भी कोई डेटा आइटम ऑब्जेक्ट बनाया जाता है, मिटाया जाता है या बदला जाता है, तो सिस्टम कनेक्ट किए गए सभी नोड पर इस कॉलबैक को ट्रिगर करता है.
  • onMessageReceived(): किसी नोड से भेजा गया मैसेज, टारगेट नोड पर इस कॉलबैक को ट्रिगर करता है.
  • onCapabilityChanged(): जब आपके ऐप्लिकेशन के किसी इंस्टेंस के विज्ञापन में बताई गई सुविधा नेटवर्क पर उपलब्ध हो जाती है, तब यह इवेंट इस कॉलबैक को ट्रिगर करता है. अगर आपको आस-पास के नोड के बारे में जानकारी चाहिए, तो कॉल बैक में दिए गए नोड के isNearby() तरीके से क्वेरी की जा सकती है.

ChannelClient.ChannelCallback से भी इवेंट सुने जा सकते हैं. जैसे, onChannelOpened().

पहले के सभी इवेंट, बैकग्राउंड थ्रेड में लागू किए जाते हैं. इन्हें मुख्य थ्रेड में लागू नहीं किया जाता.

WearableListenerService बनाने के लिए, यह तरीका अपनाएं:

  1. WearableListenerService को बढ़ाने वाली क्लास बनाएं.
  2. अपनी पसंद के इवेंट सुनें, जैसे कि onDataChanged().
  3. अपने Android मेनिफ़ेस्ट में इंटेंट फ़िल्टर का एलान करें, ताकि सिस्टम को आपके WearableListenerService के बारे में सूचना मिल सके. इस एलान से सिस्टम को आपकी सेवा को ज़रूरत के हिसाब से बाइंड करने की अनुमति मिलती है.

यहां दिए गए उदाहरण में, WearableListenerService को लागू करने का तरीका बताया गया है:

class DataLayerListenerService : WearableListenerService() {

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "onDataChanged: $dataEvents")
        }

        // Loop through the events and send a message
        // to the node that created the data item.
        dataEvents
            .map { it.dataItem.uri }
            .forEach { uri ->
                // Get the node ID from the host value of the URI.
                val nodeId: String = uri.host!!
                // Set the data of the message to be the bytes of the URI.
                val payload: ByteArray = uri.toString().toByteArray()

                // Send the RPC.
                Wearable.getMessageClient(this)
                    .sendMessage(
                        nodeId,
                        DATA_ITEM_RECEIVED_PATH,
                        payload
                    )
            }
    }
}

यहां बताया गया है कि इस लिसनर के साथ इंटेंट फ़िल्टर का इस्तेमाल कैसे किया जाता है.

WearableListenerService के साथ फ़िल्टर इस्तेमाल करना

पिछले सेक्शन में दिखाए गए WearableListenerService उदाहरण के लिए इंटेंट फ़िल्टर ऐसा दिख सकता है:

<service
    android:name=".snippets.datalayer.DataLayerListenerService"
    android:exported="true"
    tools:ignore="ExportedService" >
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
        <data
            android:scheme="wear"
            android:host="*"
            android:path="/start-activity" />
    </intent-filter>
</service>

DATA_CHANGED ऐक्शन फ़िल्टर, सिस्टम को बताता है कि आपका ऐप्लिकेशन, डेटा लेयर इवेंट में दिलचस्पी रखता है.

इस उदाहरण में, स्मार्टवॉच /start-activity डेटा आइटम के लिए सुनता है और फ़ोन /data-item-received (DATA_ITEM_RECEIVED_PATH) मैसेज के जवाब के लिए सुनता है.

Android फ़िल्टर मैच करने के मानक नियम लागू होते हैं. हर मेनिफ़ेस्ट के लिए कई सेवाएं, हर सेवा के लिए कई इंटेंट फ़िल्टर, हर फ़िल्टर के लिए कई कार्रवाइयां, और हर फ़िल्टर के लिए कई डेटा स्टैंज़ा तय किए जा सकते हैं. फ़िल्टर, वाइल्डकार्ड होस्ट या किसी खास होस्ट से मैच कर सकते हैं. वाइल्डकार्ड होस्ट से मिलान करने के लिए, host="*" का इस्तेमाल करें. किसी खास होस्ट से मैच करने के लिए, host=<node_id> की वैल्यू तय करें.

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

Wear OS में इस्तेमाल किए जा सकने वाले फ़िल्टर टाइप के बारे में ज़्यादा जानने के लिए, WearableListenerService के लिए एपीआई रेफ़रंस दस्तावेज़ देखें.

डेटा फ़िल्टर और मैचिंग के नियमों के बारे में ज़्यादा जानने के लिए, <data> मेनिफ़ेस्ट एलिमेंट के लिए एपीआई रेफ़रंस दस्तावेज़ देखें.

इन्टेंट फ़िल्टर मैच करते समय, इन दो ज़रूरी नियमों का ध्यान रखें:

  • अगर इंटेंट फ़िल्टर के लिए कोई स्कीम तय नहीं की गई है, तो सिस्टम अन्य सभी यूआरआई एट्रिब्यूट को अनदेखा कर देता है.
  • अगर फ़िल्टर के लिए कोई होस्ट तय नहीं की गई है, तो सिस्टम सभी पाथ एट्रिब्यूट को अनदेखा कर देता है.

लाइव लिसनर का इस्तेमाल करना

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

डेटा इवेंट को सुनने वाली गतिविधि बनाने के लिए, यह तरीका अपनाएं:

  1. ज़रूरी इंटरफ़ेस लागू करें.
  2. onCreate() या onResume() तरीके में, Wearable.getDataClient(this).addListener(), MessageClient.addListener(), CapabilityClient.addListener() या ChannelClient.registerChannelCallback() को कॉल करें, ताकि Google Play services को यह सूचना दी जा सके कि आपकी गतिविधि को डेटा लेयर इवेंट में दिलचस्पी है.
  3. onStop() या onPause() में, DataClient.removeListener(), MessageClient.removeListener(), CapabilityClient.removeListener() या ChannelClient.unregisterChannelCallback() का इस्तेमाल करके रजिस्टर किए गए सभी लिसनर को अनरजिस्टर करें.
  4. अगर किसी गतिविधि को सिर्फ़ किसी खास पाथ प्रीफ़िक्स वाले इवेंट पाने हैं, तो प्रीफ़िक्स फ़िल्टर वाला लिसनर जोड़ें. इससे सिर्फ़ मौजूदा ऐप्लिकेशन की स्थिति से जुड़ा डेटा मिलेगा.
  5. आपने जिन इंटरफ़ेस को लागू किया है उनके हिसाब से, onDataChanged(), onMessageReceived(), onCapabilityChanged() या ChannelClient.ChannelCallback के तरीकों को लागू करें. इन तरीकों को मुख्य थ्रेड पर कॉल किया जाता है. इसके अलावा, WearableOptions का इस्तेमाल करके, कस्टम Looper तय किया जा सकता है.

यहां DataClient.OnDataChangedListener को लागू करने का एक उदाहरण दिया गया है:

class MainActivity : Activity(), DataClient.OnDataChangedListener {

    public override fun onResume() {
        super.onResume()
        Wearable.getDataClient(this).addListener(this)
    }

    override fun onPause() {
        super.onPause()
        Wearable.getDataClient(this).removeListener(this)
    }

    override fun onDataChanged(dataEvents: DataEventBuffer) {
        dataEvents.forEach { event ->
            if (event.type == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.dataItem.uri)
            } else if (event.type == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.dataItem.uri)
            }
        }
    }
}

चेतावनी: Wearable Data Layer API का इस्तेमाल करने से पहले, यह देख लें कि यह किसी डिवाइस पर उपलब्ध है या नहीं. ऐसा न करने पर, एक अपवाद होता है. GoogleApiAvailability क्लास का इस्तेमाल करें. इसे Horologist में लागू किया गया है.

लाइव सुनने वाले लोगों के लिए फ़िल्टर इस्तेमाल करना

जैसा कि पहले बताया गया है, मेनिफ़ेस्ट पर आधारित WearableListenerService ऑब्जेक्ट के लिए इंटेंट फ़िल्टर तय किए जा सकते हैं. इसी तरह, Wearable API के ज़रिए लाइव लिसनर रजिस्टर करते समय, इंटेंट फ़िल्टर का इस्तेमाल किया जा सकता है. ये नियम, एपीआई पर आधारित लाइव लिसनर और मेनिफ़ेस्ट पर आधारित लिसनर, दोनों पर लागू होते हैं.

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