هنگامی که با Data Layer API تماس می گیرید، می توانید وضعیت تماس را پس از اتمام آن دریافت کنید. همچنین میتوانید به رویدادهای داده ناشی از تغییرات دادهای که برنامه شما در هر نقطه از شبکه Wear OS by Google ایجاد میکند گوش دهید.
برای مثالی از کار موثر با API لایه داده، برنامه Android DataLayer Sample را بررسی کنید.
منتظر وضعیت تماس های لایه داده باشید
فراخوانی به API لایه داده - مانند فراخوانی با استفاده از روش putDataItem
کلاس DataClient
- گاهی اوقات یک شی Task<ResultType>
برمی گرداند. به محض ایجاد شی Task
، عملیات در پس زمینه در صف قرار می گیرد. اگر بعد از این کار دیگری انجام ندهید، در نهایت عملیات بی صدا کامل می شود.
با این حال، شما معمولاً می خواهید پس از اتمام عملیات کاری با نتیجه انجام دهید، بنابراین شی Task
به شما امکان می دهد تا برای وضعیت نتیجه، چه به صورت ناهمزمان یا چه همزمان، منتظر بمانید.
تماس های ناهمزمان
اگر کد شما روی رشته رابط کاربری اصلی اجرا میشود، از برقراری تماسهای مسدودکننده با Data Layer API خودداری کنید. با افزودن یک متد پاسخ به تماس به شیء 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>) { ... }
جاوا
// Using Java 8 Lambdas. task.addOnSuccessListener(dataItem -> handleDataItem(dataItem)); task.addOnFailureListener(exception -> handleDataItemError(exception)); task.addOnCompleteListener(task -> handleTaskComplete(task));
برای سایر امکانات، از جمله زنجیره اجرای وظایف مختلف، به Task API مراجعه کنید.
تماس های همزمان
اگر کد شما روی یک رشته کنترل کننده جداگانه در یک سرویس پسزمینه اجرا میشود، مانند WearableListenerService
، مسدود شدن تماسها خوب است. در این حالت، میتوانید Tasks.await()
را در شیء Task
فراخوانی کنید، که تا زمانی که درخواست تکمیل شود مسدود میشود و یک شی Result
برمیگرداند. این در مثال زیر نشان داده شده است.
توجه: مطمئن شوید که وقتی در تاپیک اصلی هستید این را صدا نکنید.
کاتلین
try { Tasks.await(dataItemTask).apply { Log.d(TAG, "Data item set: $uri") } } catch (e: ExecutionException) { ... } catch (e: InterruptedException) { ... }
جاوا
try { DataItem item = Tasks.await(dataItemTask); Log.d(TAG, "Data item set: " + item.getUri()); } catch (ExecutionException | InterruptedException e) { ... }
به رویدادهای لایه داده گوش دهید
از آنجایی که لایه داده، دادهها را بین دستگاههای دستی و پوشیدنی همگامسازی و ارسال میکند، معمولاً باید به رویدادهای مهم مانند موارد دادهای که ایجاد میشوند و پیامهایی که دریافت میشوند گوش دهید.
برای گوش دادن به رویدادهای لایه داده، دو گزینه دارید:
- سرویسی ایجاد کنید که
WearableListenerService
را گسترش دهد. - یک اکتیویتی یا کلاسی ایجاد کنید که رابط
DataClient.OnDataChangedListener
را پیاده سازی کند.
با هر دوی این گزینهها، روشهای برگشت تماس رویداد دادهها را برای رویدادهایی که میخواهید مدیریت کنید لغو میکنید.
توجه: هنگام انتخاب اجرای شنونده، مصرف باتری برنامه خود را در نظر بگیرید. یک WearableListenerService
در مانیفست برنامه ثبت شده است و اگر برنامه از قبل اجرا نشده باشد، می تواند آن را راه اندازی کند. اگر فقط زمانی نیاز دارید که به رویدادها گوش دهید که برنامه شما در حال اجرا است، که اغلب در مورد برنامه های تعاملی صادق است، از WearableListenerService
استفاده نکنید. در عوض، یک شنونده زنده ثبت نام کنید. برای مثال از متد addListener
کلاس DataClient
استفاده کنید. این می تواند بار روی سیستم را کاهش دهد و مصرف باتری را کاهش دهد.
از WearableListenerService استفاده کنید
شما معمولاً نمونه هایی از WearableListenerService
را هم در برنامه های پوشیدنی و هم در برنامه های دستی خود ایجاد می کنید. با این حال، اگر به رویدادهای داده در یکی از برنامهها علاقه ندارید، نیازی به پیادهسازی سرویس در آن برنامه ندارید.
به عنوان مثال، می توانید یک برنامه دستی داشته باشید که اشیاء مورد داده را تنظیم و دریافت می کند و یک برنامه پوشیدنی که به این به روز رسانی ها گوش می دهد تا رابط کاربری خود را به روز کند. برنامه پوشیدنی هرگز هیچ یک از موارد داده را به روز نمی کند، بنابراین برنامه دستی به هیچ رویداد داده ای از برنامه پوشیدنی گوش نمی دهد.
برخی از رویدادهایی که میتوانید با استفاده از WearableListenerService
به آن گوش دهید، به شرح زیر است:
-
onDataChanged()
: هر زمان که یک شی مورد داده ایجاد، حذف یا تغییر میکند، سیستم این تماس را در تمام گرههای متصل آغاز میکند. -
onMessageReceived()
: پیامی که از یک گره ارسال می شود، این تماس را در گره مورد نظر آغاز می کند. -
onCapabilityChanged()
: وقتی قابلیتی که نمونهای از برنامه شما تبلیغ میکند در شبکه در دسترس قرار میگیرد، آن رویداد این تماس را فعال میکند. اگر به دنبال یک گره در نزدیکی هستید، میتوانید روشisNearby()
گرههای ارائه شده در callback را پرس و جو کنید.
همچنین میتوانید رویدادها را از ChannelClient.ChannelCallback
، مانند onChannelOpened()
گوش دهید.
همه رویدادهای قبلی در یک رشته پسزمینه اجرا میشوند، نه در رشته اصلی.
برای ایجاد WearableListenerService
، این مراحل را دنبال کنید:
- کلاسی ایجاد کنید که
WearableListenerService
را گسترش دهد. - به رویدادهایی که به آنها علاقه دارید، مانند
onDataChanged()
گوش دهید. - یک فیلتر قصد در مانیفست Android خود اعلام کنید تا سیستم را در مورد
WearableListenerService
خود مطلع کنید. این اعلان به سیستم اجازه میدهد سرویس شما را در صورت لزوم متصل کند.
مثال زیر نحوه پیاده سازی WearableListenerService
ساده را نشان می دهد:
کاتلین
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) } } }
جاوا
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
گوش می دهد.
قوانین استاندارد مطابقت فیلتر اندروید اعمال می شود. میتوانید چندین سرویس در هر مانیفست، چندین فیلتر هدف در هر سرویس، چندین عمل در هر فیلتر، و چند بند داده در هر فیلتر مشخص کنید. فیلترها می توانند بر روی یک میزبان عام یا در یک میزبان خاص مطابقت داشته باشند. برای تطبیق در یک میزبان عام، از host="*"
استفاده کنید. برای مطابقت در یک میزبان خاص، host=<node_id>
را مشخص کنید.
شما همچنین می توانید یک مسیر تحت اللفظی یا پیشوند مسیر را مطابقت دهید. برای انجام این کار، باید یک عام یا هاست خاص را مشخص کنید. در غیر این صورت، سیستم مسیری که شما مشخص کرده اید را نادیده می گیرد.
برای اطلاعات بیشتر در مورد انواع فیلترهایی که Wear OS پشتیبانی می کند، به مستندات مرجع API برای WearableListenerService
مراجعه کنید.
برای اطلاعات بیشتر درباره فیلترهای داده و قوانین تطبیق، به مستندات مرجع API برای عنصر مانیفست <data>
مراجعه کنید.
هنگام تطبیق فیلترهای هدف، دو قانون مهم را به خاطر بسپارید:
- اگر هیچ طرحی برای فیلتر intent مشخص نشده باشد، سیستم تمام ویژگی های URI دیگر را نادیده می گیرد.
- اگر هیچ میزبانی برای فیلتر مشخص نشده باشد، سیستم تمام ویژگی های مسیر را نادیده می گیرد.
از شنونده زنده استفاده کنید
اگر برنامه شما زمانی که کاربر در حال تعامل با برنامه است فقط به رویدادهای لایه داده اهمیت می دهد، ممکن است برای مدیریت هر تغییر داده نیازی به سرویس طولانی مدت نداشته باشد. در چنین حالتی، میتوانید با اجرای یک یا چند رابط زیر به رویدادهای یک فعالیت گوش دهید:
-
DataClient.OnDataChangedListener
-
MessageClient.OnMessageReceivedListener
-
CapabilityClient.OnCapabilityChangedListener
-
ChannelClient.ChannelCallback
برای ایجاد فعالیتی که به رویدادهای داده گوش می دهد، موارد زیر را انجام دهید:
- رابط های مورد نظر را پیاده سازی کنید.
- در روش
onCreate()
یاonResume()
، باWearable.getDataClient(this).addListener()
,MessageClient.addListener()
,CapabilityClient.addListener()
یاChannelClient.registerChannelCallback()
بگیرید تا به شما اطلاع دهید که فعالیت شما در Google Play است. علاقه مند به گوش دادن به رویدادهای لایه داده است. - در
onStop()
یاonPause()
، هر شنونده را باDataClient.removeListener()
،MessageClient.removeListener()
،CapabilityClient.removeListener()
یاChannelClient.unregisterChannelCallback()
لغو ثبت کنید. - اگر فعالیتی فقط به رویدادهایی با پیشوند مسیر خاص علاقه دارد، می توانید شنونده ای با فیلتر پیشوند مناسب اضافه کنید تا فقط داده هایی را دریافت کند که مربوط به وضعیت فعلی برنامه است.
-
onDataChanged()
،onMessageReceived()
،onCapabilityChanged()
یا متدهایی را ازChannelClient.ChannelCallback
، بسته به رابطهایی که پیادهسازی کردهاید، پیادهسازی کنید. این روشها در رشته اصلی فراخوانی میشوند، یا میتوانید یکLooper
سفارشی را با استفاده ازWearableOptions
تعیین کنید.
در اینجا یک مثال است که DataClient.OnDataChangedListener
را پیاده سازی می کند:
کاتلین
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) } } } }
جاوا
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
مبتنی بر مانیفست تعیین کنید، می توانید هنگام ثبت شنونده زنده از طریق Wearable API از فیلترهای هدف استفاده کنید. قوانین یکسانی برای شنوندگان زنده مبتنی بر API و شنوندگان مبتنی بر مانیفست اعمال می شود.
یک الگوی رایج این است که یک شنونده را با یک مسیر یا پیشوند مسیر خاص در متد onResume()
یک فعالیت ثبت کنید و سپس شنونده را در متد onPause()
فعالیت حذف کنید. اجرای شنوندگان به این روش به برنامه شما امکان می دهد رویدادها را به صورت انتخابی دریافت کند و طراحی و کارایی آن را بهبود بخشد.