عند إجراء اتصال بواجهة برمجة تطبيقات طبقة البيانات، يمكنك استلام حالة المكالمة عند اكتمالها. يمكنك أيضًا الاستماع إلى أحداث البيانات الناتجة عن التغييرات في البيانات التي يُجريها تطبيقك في أي مكان على شبكة Wear OS من Google.
كمثال على العمل بفعالية باستخدام واجهة برمجة تطبيقات طبقة البيانات، اطلع على تطبيق Android DataLayer Sample
انتظار حالة استدعاءات طبقة البيانات
الطلبات إلى Data Layer API، مثل إجراء استدعاء باستخدام 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
،
فلا بأس من حظر المكالمات. في هذه الحالة، يمكنك الاتصال بـ Tasks.await()
على Task
كائنًا، والذي يمنع اكتمال الطلب وعرض
الكائن 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
بدلاً من ذلك، يمكنك تسجيل مستمع مباشر.
على سبيل المثال، يمكنك استخدام طريقة addListener
من DataClient
.
الصف. ويمكن أن يؤدي هذا إلى تقليل الحمل على النظام وتقليل استخدام البطارية.
استخدام WearableListenerService
عادةً ما تنشئ مثيلات من
WearableListenerService
في كل من الجهاز القابل للارتداء
التطبيقات المحمولة باليد. ومع ذلك، إذا لم تكن مهتمًا بأحداث البيانات في أحد
فلن تحتاج إلى تنفيذ الخدمة في هذا التطبيق.
على سبيل المثال، يمكن أن يكون لديك تطبيق محمول باليد يضبط عناصر عناصر البيانات ويحصل عليها. وتطبيق قابل للارتداء يستمع إلى هذه التحديثات لتحديث واجهة المستخدم الخاصة به. تشير رسالة الأشكال البيانية لا يحدّث تطبيق الأجهزة القابلة للارتداء أيًا من عناصر البيانات، لذا لا استمع إلى أي أحداث بيانات من تطبيق الأجهزة القابلة للارتداء.
بعض الأحداث التي يمكنك الاستماع إليها باستخدام
WearableListenerService
هي ما يلي:
-
onDataChanged()
: فعندما يتم إنشاء كائن بيانات أو حذفه أو تغييره، فإن النظام رد الاتصال هذا على جميع العُقد المتصلة. -
onMessageReceived()
: رسالة مُرسَلة من مشغِّلات عُقد رد الاتصال هذا على العقدة المستهدفة. -
onCapabilityChanged()
: عندما تتوفّر ميزة يُعلن عنها نسخة من تطبيقك على الشبكة، يؤدي هذا الحدث إلى تشغيل معاودة الاتصال هذه. إذا كنت تبحث عن العقدة القريبة، يمكنك الاستعلام عنisNearby()
للعُقد المتوفرة في معاودة الاتصال.
يمكنك أيضًا الاستماع إلى أحداث من
ChannelClient.ChannelCallback
، مثل onChannelOpened()
.
ويتم تنفيذ جميع الأحداث السابقة في سلسلة محادثات في الخلفية، وليس في سلسلة التعليمات الرئيسية.
لإنشاء WearableListenerService
، يُرجى اتّباع الخطوات التالية:
- أنشِئ صفًا يمتد إلى
WearableListenerService
. - يمكنك الاستماع إلى الأحداث التي تهمّك، مثل
onDataChanged()
. - يُرجى تعريف فلتر الأهداف في ملف بيان 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، يُرجى الاطّلاع على
وثائق واجهة برمجة التطبيقات المرجعية لـ
WearableListenerService
لمزيد من المعلومات حول فلاتر البيانات والقواعد المطابقة، يُرجى الاطّلاع على مرجع واجهة برمجة التطبيقات.
مستندات حول <data>
عنصر البيان.
عند مطابقة فلاتر الأهداف، تذكّر قاعدتَين مهمتَين:
- في حال عدم تحديد أي مخطط لفلتر الأهداف، يتجاهل النظام جميع سمات معرف الموارد المنتظم (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
:
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
مستندة إلى البيان
يمكنك استخدام فلاتر الأهداف عند تسجيل مستمع مباشر من خلال
يمكن ارتداؤها
واجهة برمجة التطبيقات. تنطبق القواعد نفسها على كل من أدوات استماع البث المباشر المستندة إلى واجهة برمجة التطبيقات
أدوات معالجة الأحداث القائمة على البيان.
هناك نمط شائع وهو تسجيل مستمع ببادئة مسار أو مسار محدد
في onResume()
لأحد الأنشطة
ثم إزالة المستمع من ورقة
طريقة onPause()
.
وتجدر الإشارة إلى أن إضافة المستمعين بهذه الطريقة يتيح لتطبيقك أن تكون أكثر انتقائية.
باستقبال الأحداث، مما يؤدي إلى تحسين تصميمه وكفاءته.