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

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

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

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

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

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

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

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

Kotlin

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

Java

// Using Java 8 Lambdas.
task.addOnSuccessListener(dataItem -> handleDataItem(dataItem));
task.addOnFailureListener(exception -> handleDataItemError(exception));
task.addOnCompleteListener(task -> handleTaskComplete(task));

Task API का इस्तेमाल अन्य विकल्पों के लिए किया जा सकता है. इसमें, किसी एक तरीके से करने में मदद मिलती है.

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

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

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

Kotlin

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

Java

try {
    DataItem item = Tasks.await(dataItemTask);
    Log.d(TAG, "Data item set: " + item.getUri());
} catch (ExecutionException | InterruptedException e) {
  ...
}

डेटा लेयर इवेंट सुनें

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

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

  • WearableListenerService के दायरे में आने वाली सेवा बनाएं.
  • ऐसी गतिविधि या क्लास बनाएं जो DataClient.OnDataChangedListener इंटरफ़ेस को लागू करती हो.

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

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

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

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

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

कुछ इवेंट जिनका इस्तेमाल किया जा सकता है WearableListenerService के बारे में यहां बताया गया है:

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

आपके पास यहां से इवेंट सुनने का भी विकल्प है ChannelClient.ChannelCallback, जैसे कि onChannelOpened().

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

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

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

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

Kotlin

private const val TAG = "DataLayerSample"
private const val START_ACTIVITY_PATH = "/start-activity"
private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received"

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

Java

public class DataLayerListenerService extends WearableListenerService {
    private static final String TAG = "DataLayerSample";
    private static final String START_ACTIVITY_PATH = "/start-activity";
    private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        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.
        for (DataEvent event : dataEvents) {
            Uri uri = event.getDataItem().getUri();

            // Get the node ID from the host value of the URI.
            String nodeId = uri.getHost();
            // Set the data of the message to be the bytes of the URI.
            byte[] payload = uri.toString().getBytes();

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

नीचे दिए गए सेक्शन में, इस लिसनर के साथ इंटेंट फ़िल्टर का इस्तेमाल करने का तरीका बताया गया है.

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

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

<service android:name=".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 कार्रवाई पहले सुझाई गई BIND_LISTENER कार्रवाई, ताकि सिर्फ़ सटीक इवेंट आपके ऐप्लिकेशन को सक्रिय या लॉन्च करते हैं. इस बदलाव से सिस्टम की परफ़ॉर्मेंस बेहतर होती है और बैटरी की खपत और आपके डिवाइस से जुड़े अन्य ओवरहेड को कम करता है है. इस उदाहरण में, स्मार्टवॉच /start-activity डेटा आइटम और फ़ोन /data-item-received मैसेज के जवाब को सुनता है.

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

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

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

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

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

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

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

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

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

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

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

Kotlin

class MainActivity : Activity(), DataClient.OnDataChangedListener {

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

    override fun 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)
            }
        }
    }
}

Java

public class MainActivity extends Activity implements DataClient.OnDataChangedListener {

    @Override
    public void onResume() {
        Wearable.getDataClient(this).addListener(this);
    }

    @Override
    protected void onPause() {
        Wearable.getDataClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        for (DataEvent event : dataEvents) {
            if (event.getType() == DataEvent.TYPE_DELETED) {
                Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
            } else if (event.getType() == DataEvent.TYPE_CHANGED) {
                Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
            }
        }
    }
}

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

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

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