যখন আপনি ডেটা লেয়ার API-তে কল করেন, তখন কলটি সম্পূর্ণ হয়ে গেলে আপনি কলটির স্থিতি পেতে পারেন। আপনি Wear OS by Google নেটওয়ার্কের যেকোনো জায়গায় আপনার অ্যাপের ডেটা পরিবর্তনের ফলে সৃষ্ট ডেটা ইভেন্টগুলিও শুনতে পারেন।
ডেটা লেয়ার এপিআই-এর সাথে কার্যকরভাবে কাজ করার একটি উদাহরণের জন্য, অ্যান্ড্রয়েড ডেটালেয়ার নমুনা অ্যাপটি দেখুন।
ডেটা লেয়ার কলের স্থিতির জন্য অপেক্ষা করুন
Data Layer API-তে কল করা হলে—যেমন DataClient ক্লাসের putDataItem পদ্ধতি ব্যবহার করে করা কল—কখনও কখনও Task<ResultType> অবজেক্ট ফেরত আসে। Task অবজেক্ট তৈরি হওয়ার সাথে সাথেই, অপারেশনটি ব্যাকগ্রাউন্ডে সারিবদ্ধ হয়ে যায়। এর পরে যদি আপনি আর কিছু না করেন, তাহলে অপারেশনটি অবশেষে নীরবে সম্পন্ন হয়।
তবে, অপারেশন সম্পন্ন হওয়ার পরে আপনি সাধারণত ফলাফলের সাথে কিছু করতে চান, তাই Task অবজেক্ট আপনাকে ফলাফলের স্থিতির জন্য অপেক্ষা করতে দেয়, হয় অ্যাসিঙ্ক্রোনাসভাবে বা সিঙ্ক্রোনাসভাবে।
অ্যাসিঙ্ক্রোনাস কল
যদি আপনার কোডটি মূল UI থ্রেডে চলমান থাকে, তাহলে Data Layer API-তে ব্লকিং কল করবেন না এবং putDataItem কল করার জন্য একটি coroutine ব্যবহার করুন:
private suspend fun Context.sendDataAsync(count: Int) { try { val putDataReq: PutDataRequest = PutDataMapRequest.create("/count").run { dataMap.putInt("count_key", count) asPutDataRequest() } val dataItem = Wearable.getDataClient(this).putDataItem(putDataReq).await() handleDataItem(dataItem) } catch (e: Exception) { handleDataItemError(e) } finally { handleTaskComplete() } } private fun handleDataItem(dataItem: DataItem) { } private fun handleDataItemError(exception: Exception) { } private fun handleTaskComplete() { }
বিভিন্ন কাজের সম্পাদনের জন্য শৃঙ্খলিতকরণ সহ অন্যান্য সম্ভাবনার জন্য টাস্ক API দেখুন।
সিঙ্ক্রোনাস কল
যদি আপনার কোডটি WearableListenerService এর মতো ব্যাকগ্রাউন্ড সার্ভিসে একটি পৃথক হ্যান্ডলার থ্রেডে চলমান থাকে, তাহলে putDataItem এ ব্লকিং কল করতে runBlocking ব্যবহার করুন।
দ্রষ্টব্য: মূল থ্রেডে থাকাকালীন এটি কল করবেন না।
private fun Context.sendDataSync(count: Int) = runBlocking { val putDataReq = PutDataMapRequest.create("/count").run { dataMap.putInt("count_key", count) asPutDataRequest() } try { val result = Wearable.getDataClient(this@sendDataSync) .putDataItem(putDataReq) .await() // Logic for success } catch (e: Exception) { // Handle failure } }
ডেটা লেয়ার ইভেন্টগুলি শুনুন
যেহেতু ডেটা স্তরটি হ্যান্ডহেল্ড এবং পরিধেয় ডিভাইসগুলিতে ডেটা সিঙ্ক্রোনাইজ করে এবং প্রেরণ করে, তাই আপনাকে সাধারণত ডেটা আইটেম তৈরি এবং বার্তা গ্রহণের মতো গুরুত্বপূর্ণ ইভেন্টগুলি শুনতে হবে।
ডেটা লেয়ার ইভেন্টগুলি শোনার জন্য, আপনার কাছে দুটি বিকল্প রয়েছে:
- এমন একটি পরিষেবা তৈরি করুন যা
WearableListenerServiceপ্রসারিত করে। -
DataClient.OnDataChangedListenerইন্টারফেসটি বাস্তবায়ন করে এমন একটি কার্যকলাপ বা ক্লাস তৈরি করুন।
এই দুটি বিকল্পের সাহায্যে, আপনি যে ইভেন্টগুলি পরিচালনা করতে আগ্রহী তার জন্য ডেটা ইভেন্ট কলব্যাক পদ্ধতিগুলিকে ওভাররাইড করেন।
দ্রষ্টব্য: শ্রোতা বাস্তবায়ন নির্বাচন করার সময় আপনার অ্যাপের ব্যাটারি ব্যবহারের কথা বিবেচনা করুন। একটি WearableListenerService অ্যাপের ম্যানিফেস্টে নিবন্ধিত থাকে এবং যদি এটি ইতিমধ্যেই চালু না থাকে তবে অ্যাপটি চালু করতে পারে। যদি আপনার অ্যাপটি ইতিমধ্যেই চলমান থাকাকালীন ইভেন্টগুলি শুনতে হয়, যা প্রায়শই ইন্টারেক্টিভ অ্যাপ্লিকেশনগুলির ক্ষেত্রে হয়, তাহলে WearableListenerService ব্যবহার করবেন না। পরিবর্তে, একটি লাইভ শ্রোতা নিবন্ধন করুন। উদাহরণস্বরূপ, DataClient ক্লাসের addListener পদ্ধতি ব্যবহার করুন। এটি সিস্টেমের উপর লোড কমাতে এবং ব্যাটারির ব্যবহার কমাতে পারে।
একটি WearableListenerService ব্যবহার করুন
আপনি সাধারণত আপনার পরিধেয় এবং হ্যান্ডহেল্ড উভয় অ্যাপেই WearableListenerService এর ইনস্ট্যান্স তৈরি করেন। তবে, যদি আপনি কোনও অ্যাপের ডেটা ইভেন্টে আগ্রহী না হন, তাহলে আপনাকে সেই অ্যাপে পরিষেবাটি বাস্তবায়ন করার প্রয়োজন নেই।
উদাহরণস্বরূপ, আপনার কাছে একটি হ্যান্ডহেল্ড অ্যাপ থাকতে পারে যা ডেটা আইটেম অবজেক্ট সেট করে এবং গ্রহণ করে এবং একটি পরিধেয় অ্যাপ থাকতে পারে যা তার UI আপডেট করার জন্য এই আপডেটগুলি শোনে। পরিধেয় অ্যাপটি কখনই কোনও ডেটা আইটেম আপডেট করে না, তাই হ্যান্ডহেল্ড অ্যাপটি পরিধেয় অ্যাপ থেকে কোনও ডেটা ইভেন্ট শোনে না।
WearableListenerService ব্যবহার করে আপনি যে ইভেন্টগুলি শুনতে পারেন তার মধ্যে কয়েকটি হল:
-
onDataChanged(): যখনই কোনও ডেটা আইটেম অবজেক্ট তৈরি, মুছে ফেলা বা পরিবর্তন করা হয়, তখন সিস্টেমটি সমস্ত সংযুক্ত নোডে এই কলব্যাকটি ট্রিগার করে। -
onMessageReceived(): একটি নোড থেকে প্রেরিত একটি বার্তা লক্ষ্য নোডে এই কলব্যাকটি ট্রিগার করে। -
onCapabilityChanged(): যখন আপনার অ্যাপের একটি ইনস্ট্যান্সের বিজ্ঞাপনে দেখানো কোনও ক্ষমতা নেটওয়ার্কে উপলব্ধ হয়, তখন সেই ইভেন্টটি এই কলব্যাকটি ট্রিগার করে। আপনি যদি কাছাকাছি কোনও নোড খুঁজছেন, তাহলে আপনি কলব্যাকে প্রদত্ত নোডগুলিরisNearby()পদ্ধতিটি অনুসন্ধান করতে পারেন।
আপনি ChannelClient.ChannelCallback থেকেও ইভেন্ট শুনতে পারেন, যেমন onChannelOpened() ।
পূর্ববর্তী সমস্ত ইভেন্টগুলি মূল থ্রেডে নয়, একটি ব্যাকগ্রাউন্ড থ্রেডে কার্যকর করা হয়।
একটি WearableListenerService তৈরি করতে, এই পদক্ষেপগুলি অনুসরণ করুন:
- এমন একটি ক্লাস তৈরি করুন যা
WearableListenerServiceপ্রসারিত করে। - আপনার আগ্রহের ইভেন্টগুলি শুনুন, যেমন
onDataChanged()। - আপনার
WearableListenerServiceসম্পর্কে সিস্টেমকে অবহিত করার জন্য আপনার Android ম্যানিফেস্টে একটি ইন্টেন্ট ফিল্টার ঘোষণা করুন। এই ঘোষণাটি সিস্টেমকে প্রয়োজন অনুসারে আপনার পরিষেবাকে আবদ্ধ করতে দেয়।
নিম্নলিখিত উদাহরণে 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 ) বার্তার প্রতিক্রিয়া শোনে।
স্ট্যান্ডার্ড অ্যান্ড্রয়েড ফিল্টার ম্যাচিং নিয়ম প্রযোজ্য। আপনি প্রতিটি ম্যানিফেস্টে একাধিক পরিষেবা, প্রতিটি পরিষেবাতে একাধিক ইন্টেন্ট ফিল্টার, প্রতিটি ফিল্টারে একাধিক ক্রিয়া এবং প্রতিটি ফিল্টারে একাধিক ডেটা স্তবক নির্দিষ্ট করতে পারেন। ফিল্টারগুলি একটি ওয়াইল্ডকার্ড হোস্টে বা একটি নির্দিষ্ট হোস্টে মিলতে পারে। একটি ওয়াইল্ডকার্ড হোস্টে মিল করতে, host="*" ব্যবহার করুন। একটি নির্দিষ্ট হোস্টে মিল করতে, host=<node_id> নির্দিষ্ট করুন।
আপনি একটি আক্ষরিক পাথ বা পাথ প্রিফিক্সও মেলাতে পারেন। এটি করার জন্য, আপনাকে একটি ওয়াইল্ডকার্ড বা নির্দিষ্ট হোস্ট নির্দিষ্ট করতে হবে। অন্যথায়, সিস্টেম আপনার নির্দিষ্ট পাথটি উপেক্ষা করবে।
Wear OS কোন ধরণের ফিল্টার সমর্থন করে সে সম্পর্কে আরও তথ্যের জন্য, WearableListenerService এর API রেফারেন্স ডকুমেন্টেশন দেখুন।
ডেটা ফিল্টার এবং ম্যাচিং নিয়ম সম্পর্কে আরও তথ্যের জন্য, <data> ম্যানিফেস্ট এলিমেন্টের জন্য API রেফারেন্স ডকুমেন্টেশন দেখুন।
ইন্টেন্ট ফিল্টার মেলানোর সময়, দুটি গুরুত্বপূর্ণ নিয়ম মনে রাখবেন:
- যদি ইন্টেন্ট ফিল্টারের জন্য কোনও স্কিম নির্দিষ্ট না করা থাকে, তাহলে সিস্টেমটি অন্যান্য সমস্ত URI বৈশিষ্ট্য উপেক্ষা করে।
- যদি ফিল্টারের জন্য কোনও হোস্ট নির্দিষ্ট না করা থাকে, তাহলে সিস্টেমটি সমস্ত পাথ অ্যাট্রিবিউট উপেক্ষা করে।
একটি লাইভ শ্রোতা ব্যবহার করুন
যদি আপনার অ্যাপটি শুধুমাত্র ডেটা-লেয়ার ইভেন্টগুলির বিষয়ে চিন্তা করে যখন ব্যবহারকারী অ্যাপের সাথে ইন্টারঅ্যাক্ট করছে, তাহলে প্রতিটি ডেটা পরিবর্তন পরিচালনা করার জন্য দীর্ঘমেয়াদী পরিষেবার প্রয়োজন নাও হতে পারে। এই ক্ষেত্রে, আপনি কোনও কার্যকলাপের ইভেন্টগুলি শুনতে পারেন।
একটি পরিষ্কার এবং নিরাপদ পদ্ধতির সুপারিশ করার জন্য, একটি Lifecycle Observer ব্যবহার করুন। একটি Lifecycle Observer ব্যবহার করে, আপনি Activity এর onResume() থেকে নিবন্ধন লজিকটি বের করে একটি পৃথক, পুনঃব্যবহারযোগ্য ক্লাসে স্থানান্তর করেন যা DefaultLifecycleObserver প্রয়োগ করে।
এই পদ্ধতিটি আপনার অ্যাক্টিভিটিকে দুর্বল রাখে এবং শ্রোতাকে নিবন্ধনমুক্ত করতে ভুলে যাওয়ার মতো সাধারণ বাগগুলি প্রতিরোধ করে।
১. জীবনচক্র-সচেতন শ্রোতা তৈরি করুন
এই ক্লাসটি DataClient.OnDataChangedListener অন্তর্ভুক্ত করে এবং Activity-এর জীবনচক্রের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে নিজস্ব সাবস্ক্রিপশন পরিচালনা করে।
class WearDataLayerObserver( private val dataClient: DataClient, private val onDataReceived: (DataEventBuffer) -> Unit ) : DefaultLifecycleObserver, DataClient.OnDataChangedListener { // Implementation of the DataClient listener override fun onDataChanged(dataEvents: DataEventBuffer) { onDataReceived(dataEvents) } // Automatically register when the Activity starts override fun onResume(owner: LifecycleOwner) { dataClient.addListener(this) } // Automatically unregister when the Activity pauses override fun onPause(owner: LifecycleOwner) { dataClient.removeListener(this) } }
2. আপনার কার্যকলাপে ব্যবহার
এখন, আপনার Activity-কে Wear API-এর জন্য onResume() বা onPause() ওভাররাইড করার প্রয়োজন নেই। আপনি onCreate() এ একবার পর্যবেক্ষক যোগ করবেন।
class DataLayerLifecycleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val dataClient = Wearable.getDataClient(this) // Create the observer and link it to the activity's lifecycle val wearObserver = WearDataLayerObserver(dataClient) { dataEvents -> handleDataEvents(dataEvents) } lifecycle.addObserver(wearObserver) } private fun handleDataEvents(dataEvents: DataEventBuffer) { // ... filter and process events ... } }
কেন এটি ভালো:
- ক্লিনার অ্যাক্টিভিটি: আপনি অ্যাক্টিভিটি লাইফসাইকেল পদ্ধতি থেকে বয়লারপ্লেটটি সরিয়ে ফেলবেন।
- নিরাপত্তা:
DefaultLifecycleObserverঅ্যাক্টিভিটি অপ্রত্যাশিতভাবে ধ্বংস হয়ে গেলেও লিসেনারটি সরানো হয়েছে কিনা তা যাচাই করতে সাহায্য করে, মেমরি লিক প্রতিরোধ করে। - পুনঃব্যবহারযোগ্যতা: আপনি রেজিস্ট্রেশন লজিক পুনর্লিখন না করেই এই
WearDataLayerObserverযেকোনো অ্যাক্টিভিটি বা ফ্র্যাগমেন্টে প্লাগ করতে পারেন। - ডিকাপলিং: কখন শুনতে হবে তার যুক্তি ডেটা দিয়ে কী করতে হবে তার যুক্তি থেকে আলাদা।
লাইভ শ্রোতাদের সাথে ফিল্টার ব্যবহার করুন
পূর্বে উল্লেখ করা হয়েছে, ঠিক যেমন আপনি ম্যানিফেস্ট-ভিত্তিক WearableListenerService অবজেক্টের জন্য ইন্টেন্ট ফিল্টার নির্দিষ্ট করতে পারেন, তেমনি Wearable API এর মাধ্যমে লাইভ লিসেনার নিবন্ধন করার সময় আপনি ইন্টেন্ট ফিল্টার ব্যবহার করতে পারেন। API-ভিত্তিক লাইভ লিসেনার এবং ম্যানিফেস্ট-ভিত্তিক লিসেনার উভয়ের ক্ষেত্রেই একই নিয়ম প্রযোজ্য।
একটি সাধারণ ধরণ হল LifecycleObserver ব্যবহার করে একটি নির্দিষ্ট পথ বা পথের উপসর্গ দিয়ে শ্রোতা নিবন্ধন করা । এই পদ্ধতিতে শ্রোতাদের বাস্তবায়নের মাধ্যমে, আপনার অ্যাপটি আরও নির্বাচনীভাবে ইভেন্টগুলি গ্রহণ করতে পারে, এর নকশা এবং দক্ষতা উন্নত করে।