تعرض تطبيقات مزوّدي البيانات معلومات للإضافات على خلفية شاشة الساعة، ما يوفّر حقولاً تحتوي على نصوص وسلاسل وصور وأرقام.
تشمل خدمة مزوِّد البيانات
ComplicationProviderService
لتقديم معلومات مفيدة مباشرةً إلى خلفية شاشة الساعة.
إنشاء مشروع لمزود بيانات
لإنشاء مشروع في "استوديو Android" لتطبيق مزوّد البيانات، يجب إكمال الخطوات التالية:
- انقر على ملف > جديد > مشروع جديد.
- في نافذة نموذج المشروع، انقر على علامة التبويب Wear OS، واختَر ما مِن نشاط، ثم انقر على التالي.
- في نافذة Configure Your Project (إعداد مشروعك)، أدخِل اسمًا لمشروعك واملأ معلومات المشروع العادية، ثم انقر على Finish (إنهاء).
- ينشئ "استوديو Android" مشروعًا باستخدام وحدة تطبيق لمزوِّد البيانات. لمزيد من المعلومات حول المشاريع في "استوديو Android"، يمكنك الاطّلاع على المقالة إنشاء مشروع.
- ابدأ تطبيق موفّر البيانات عن طريق إنشاء صف جديد يضم
BroadcastReceiver
. الغرض من هذه الصف هو الاستماع إلى طلبات تحديث الإضافات الواردة من نظام Wear OS. بالإضافة إلى ذلك، يمكنك إنشاء فئة جديدة يتم فيها توسيع نطاقComplicationProviderService
لتوفير البيانات كما هو مطلوب من خلال الإضافات المناسبة. لمزيد من المعلومات، يُرجى الاطّلاع على ما يلي:- تنفيذ طريقة لطلبات التعديل
- صفا
ComplicationTapBroadcastReceiver
وCustomComplicationProviderService
في الدرس التطبيقي التالي حول الترميز: عرض البيانات للاطّلاع على الإضافات التي تتم إضافتها إلى خلفية شاشة الساعة على نظام التشغيل Wear OS ComplicationToggleReceiver
وLongTextProviderService
وصفوف أخرى في نموذج مجموعة الاختبار
ملاحظة: إنّ إضافة نشاط لموفّر البيانات اختيارية. على سبيل المثال، قد تحتاج إلى نشاط لا يتم تشغيله إلا عند نقر المستخدم على إحدى الإضافات.
تنفيذ طريقة لطلبات التعديل
عند الحاجة إلى إضافة بيانات، يرسِل نظام Wear OS طلبات التعديل إلى مقدّم البيانات. وتتلقّى الطلبات
BroadcastReceiver
. للردّ على طلبات التعديل،
على مزوِّد البيانات تنفيذ
طريقة
onComplicationUpdate()
للفئة ComplicationProviderService
.
يستدعي نظام Wear OS onComplicationUpdate()
عندما يحتاج إلى بيانات من موفّر الخدمة، على سبيل المثال، عند تفعيل إضافة تستخدم مقدّم الخدمة أو عند انقضاء فترة زمنية ثابتة.
ويمرِّر عنصر
ComplicationManager
كمَعلمة إلى
onComplicationUpdate
، والتي تُستخدم لإرسال البيانات مرة أخرى إلى النظام.
ملاحظة: عندما يقدّم تطبيق مزوِّد البيانات بيانات، تتلقّى خلفية شاشة الساعة القيم الأولية التي ترسلها لكي ترسم المعلومات.
يعرض مقتطف الرمز التالي نموذجًا لتنفيذ طريقة onComplicationUpdate
:
Kotlin
override fun onComplicationUpdate( complicationId: Int, dataType: Int, complicationManager: ComplicationManager) { Log.d(TAG, "onComplicationUpdate() id: $complicationId") // Used to create a unique key to use with SharedPreferences for this complication. val thisProvider = ComponentName(this, javaClass) // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs. val preferences = getSharedPreferences(ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0) val number = preferences.getInt( ComplicationTapBroadcastReceiver.getPreferenceKey( thisProvider, complicationId), 0) val numberText = String.format(Locale.getDefault(), "%d!", number) var complicationData: ComplicationData? = null when (dataType) { ComplicationData.TYPE_SHORT_TEXT -> complicationData = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(numberText)) .build() else -> if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unexpected complication type $dataType") } } if (complicationData != null) { complicationManager.updateComplicationData(complicationId, complicationData) } else { // If no data is sent, we still need to inform the ComplicationManager, so // the update job can finish and the wake lock isn't held any longer. complicationManager.noUpdateRequired(complicationId) } }
Java
@Override public void onComplicationUpdate( int complicationId, int dataType, ComplicationManager complicationManager) { Log.d(TAG, "onComplicationUpdate() id: " + complicationId); // Used to create a unique key to use with SharedPreferences for this complication. ComponentName thisProvider = new ComponentName(this, getClass()); // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs. SharedPreferences preferences = getSharedPreferences( ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0); int number = preferences.getInt( ComplicationTapBroadcastReceiver.getPreferenceKey( thisProvider, complicationId), 0); String numberText = String.format(Locale.getDefault(), "%d!", number); ComplicationData complicationData = null; switch (dataType) { case ComplicationData.TYPE_SHORT_TEXT: complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(numberText)) .build(); break; default: if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unexpected complication type " + dataType); } } if (complicationData != null) { complicationManager.updateComplicationData(complicationId, complicationData); } else { // If no data is sent, we still need to inform the ComplicationManager, so // the update job can finish and the wake lock isn't held any longer. complicationManager.noUpdateRequired(complicationId); } }
نماذج البيان والأذونات
يجب أن تتضمّن تطبيقات مزوّدي البيانات تعريفات محددة في ملف بيان التطبيق الخاص بها لكي يتم التعامل مع هذه التطبيقات باعتبارها مزوِّد بيانات من خلال نظام Android. يوضّح هذا القسم الإعدادات المطلوبة لتطبيقات مزوّدي البيانات.
في ملف البيان الخاص بتطبيقك، عليك تعريف الخدمة وإضافة فلتر لأهداف إجراء طلب التحديث.
يجب أن يحمي البيان أيضًا الخدمة من خلال إضافة إذن BIND_COMPLICATION_PROVIDER
لضمان ربط نظام Wear OS فقط بخدمات مقدِّم الخدمة.
ويجب أيضًا تضمين السمة android:icon
في العنصر service
الذي يوفّر رمزًا أبيض أحادي اللون. نوصي باستخدام رسومات متجهات للأيقونات.
يمثّل الرمز مقدّم الخدمة ويظهر في أداة اختيار الموفّر.
إليك مثال على ذلك:
<service android:name=".provider.IncrementingNumberComplicationProviderService" android:icon="@drawable/icn_complications" android:label="@string/complications_provider_incrementing_number" android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER"> <intent-filter> <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/> </intent-filter> </service>
تحديد عناصر البيانات الوصفية
في ملف البيان، ضمِّن البيانات الوصفية لتحديد الأنواع المتوافقة وفترة التحديث وإجراء الإعداد، كما هو موضّح في المثال التالي:
<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES" android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT" /> <meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="300" />
عندما يكون مزوِّد بيانات الإضافة نشطًا،
تحدّد السمة UPDATE_PERIOD_SECONDS
عدد المرات التي تريد أن
يتحقق فيها النظام من وجود تعديلات على البيانات. إذا كانت المعلومات الظاهرة في
الإضافة لا تحتاج إلى تعديل المعلومات في جدول زمني منتظم، مثلاً عند
استخدام التعديلات الفورية، اضبط هذه القيمة على
0
.
إذا لم تضبط UPDATE_PERIOD_SECONDS
على 0
،
يجب استخدام قيمة لا تقل عن 300
(5 دقائق)، وهي
الحد الأدنى لفترة التحديث التي يفرضها النظام، للحفاظ على عمر بطارية الجهاز. بالإضافة إلى ذلك، يُرجى العلِم بأنّ طلبات التحديث تأتي بمعدّل أقل عندما يكون الجهاز في وضع الاستراحة أو عندما لا يتم ارتداء الجهاز.
لمزيد من التفاصيل حول إرسال التعديلات، يمكنك الاطّلاع على المفاتيح المدرَجة في الفئة
ComplicationProviderService
في
مرجع واجهة برمجة تطبيقات Wear OS.
إضافة نشاط ضبط
يمكن لموفّر الخدمة تضمين نشاط ضبط يظهر للمستخدم عندما يختار مزوّد بيانات، إذا لزم الأمر. لتضمين نشاط الإعداد، يجب تضمين عنصر بيانات وصفية في بيان خدمة الموفّر في البيان باستخدام المفتاح التالي:
<meta-data android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION" android:value="PROVIDER_CONFIG_ACTION"/>
يمكن أن تكون القيمة أي إجراء.
بعد ذلك، يمكنك إنشاء نشاط الإعداد باستخدام فلتر أهداف لهذا الإجراء. يجب أن يكون نشاط الإعداد في الحزمة نفسها التي يستخدمها الموفّر. يجب أن يعرض نشاط الإعداد RESULT_OK
أو RESULT_CANCELED
لإعلام النظام بما إذا كان يجب ضبط مقدّم الخدمة أم لا.
خلفيات شاشة آمنة يحددها مقدّم الخدمة
يمكن لمقدّمي الخدمات تحديد خلفيات معيّنة لشاشة الساعة كـ "آمنة" لتلقّي بياناتهم. لا تُستخدَم هذه الطريقة إلا عندما تحاول خلفية شاشة الساعة استخدام مقدِّم الخدمة كخيار تلقائي وعندما يثق مقدِّم الخدمة في تطبيق خلفية شاشة الساعة.
لتعريف خلفيات شاشة الساعة بأنّها آمنة، يضيف مقدّم الخدمة بيانات وصفية باستخدام مفتاح android.support.wearable.complications.SAFE_WATCH_FACES
. وتكون قيمة البيانات الوصفية عبارة عن قائمة مفصولة بفواصل تتألف من أسماء مكونات
WatchFaceService
، ويتم تحديدها كما لو تم استدعاء ComponentName.flattenToString()
، أو أسماء حِزم التطبيقات. وفي هذه الحالة، تُعتبر كل خلفية شاشة ساعة داخل تطبيق محدّد آمنة. يتم تجاهل المسافة البيضاء في قائمة القيم. على سبيل المثال:
<meta-data android:name="android.support.wearable.complications.SAFE_WATCH_FACES" android:value=" com.app.watchface/com.app.watchface.MyWatchFaceService, com.anotherapp.anotherwatchface/com.something.WatchFaceService, com.something.text"/>
توفير صور آمنة محروقة
على الشاشات المعرّضة للتلف، يجب تجنُّب كتل الألوان الصلبة في "وضع الإضاءة السينمائية". إذا كانت الرموز أو الصور تتضمن كتلاً خالصة من الألوان، قدِّم أيضًا نسخة آمنة مُدمَجة.
عند تقديم رمز باستخدام
ComplicationData.Builder#setIcon
، ضمِّن نسخة آمنة ومضمّنة باستخدام
ComplicationData.Builder#setBurnInProtectionIcon
.
عند تقديم صورة باستخدام
ComplicationData.Builder#setSmallImage
، ضمِّن نسخة آمنة ومضمّنة باستخدام
ComplicationData.Builder#setBurnInProtectionSmallImage
.
استخدام التحديثات الفورية
وكبديل لتحديد فاصل زمني ثابت غير صفري للتحديث
لأحد الإضافات في ملف بيان تطبيقك، يمكنك استخدام مثيل
ComplicationDataSourceUpdateRequester
لطلب التحديثات بشكل ديناميكي.
لطلب تعديل المحتوى المرئي للمستخدمين في الإضافة، اتصل بـ
requestUpdate()
.
تحذير: للحفاظ على عمر بطارية الجهاز،
يجب عدم طلب الرقم requestUpdate()
من مثيل "ComplicationDataSourceUpdateRequester
" بمعدّل
يتجاوز كل 5 دقائق في المتوسط.
تقديم قيم ديناميكية
بدءًا من نظام التشغيل Wear OS 4، يمكن أن تعرض بعض الإضافات قيمًا يتم إعادة تحميلها بمعدّل أكبر
استنادًا إلى القيم المتاحة على النظام الأساسي مباشرةً. لتوفير هذه الميزة في
الإضافات، استخدِم حقول
ComplicationData
التي تقبل
القيم الديناميكية. وتقيّم المنصة هذه القيم وتعدّلها بشكل متكرّر بدون الحاجة إلى تشغيل موفّر الإضافات.
تتضمن أمثلة الحقول
حقل القيمة الديناميكية للسمة GoalProgressComplicationData
و
DynamicComplicationText
، والتي يمكن استخدامها في أي حقل
ComplicationText
. تستند هذه القيم الديناميكية إلى مكتبة
androidx.wear.protolayout.expression
.
في بعض الحالات، لا يمكن للنظام الأساسي تقييم القيم الديناميكية:
- لا تتوفّر القيمة الديناميكية أحيانًا: يحدث ذلك مثلاً عندما لا يكون الجهاز في معصمك. في هذه الحالات، تستخدم المنصة قيمة
الحقل الاحتياطي لإلغاء القيمة الديناميكية بدلاً من ذلك، في
حقل العنصر النائب في
NoDataComplicationData
. - القيمة الديناميكية غير متاحة على الإطلاق: يحدث هذا الإجراء على جهاز يعمل على إصدار قديم من Wear OS 4. في هذه الحالة، يستخدم النظام الأساسي حقلاً احتياطيًا مصاحبًا،
مثل
getFallbackValue()
.
تقديم قيم تعتمد على الوقت
وهناك بعض التعقيدات التي تحتاج إلى عرض قيمة مرتبطة بالوقت الحالي. وتشمل الأمثلة التاريخ الحالي أو الوقت المتبقي حتى الاجتماع التالي أو الوقت في منطقة زمنية أخرى.
ويجب عدم تعديل إحدى الإضافات كل ثانية أو دقيقة لإبقاء هذه القيم محدّثة. بدلاً من ذلك، حدِّد القيم على أنّها نسبية إلى التاريخ أو الوقت الحاليَين باستخدام نص يعتمد على الوقت.
يمكنك استخدام أدوات الإنشاء في الفئة
ComplicationText
لإنشاء هذه القيم التي تعتمد على الوقت.
معدّل التعديلات المُضافة
قد تحتاج إلى تعديل الإضافات بمعدل سريع. ومع ذلك، قد يؤثر ذلك في عمر بطارية الجهاز. يمكنك اختيار استخدام واجهة برمجة تطبيقات طلب الإضافة المميّزة التي تتيح تعديل إضافات معيّنة بشكل متكرّر. مع ذلك، يجب أن تسمح الشركة المصنّعة للساعة باستخدام واجهة برمجة التطبيقات هذه. تحدّد كل شركة مصنّعة للساعة الإضافات التي يمكن تحديثها بمعدّل أسرع مما هو مسموح به عادةً.