غالبًا ما تُستخدم أجهزة Wear OS لتجارب طويلة الأمد، مثل تتبُّع التمارين الرياضية. يطرح ذلك تحديًا في تجربة المستخدم: إذا بدأ المستخدم مهمة ثم انتقل إلى خلفية شاشة الساعة، كيف يمكنه العودة إلى المهمة؟ قد يكون الرجوع إلى التطبيق باستخدام مشغّل التطبيقات أمرًا صعبًا، خاصةً أثناء التنقّل، ما يؤدي إلى حدوث مشاكل غير ضرورية.
الحلّ هو إقران إشعار مستمر بـ OngoingActivity
.
يسمح هذا الإذن للجهاز بعرض معلومات حول النشاط الذي يستغرق وقتًا طويلاً في واجهة المستخدم، ما يتيح ميزات مثل الرمز القابل للنقر في أسفل خلفية شاشة الساعة. ويتيح ذلك للمستخدمين معرفة المهمة التي يتم تنفيذها في الخلفية، كما يوفّر طريقة للعودة إلى التطبيق بنقرة واحدة.
على سبيل المثال، في تطبيق التمارين الرياضية هذا، يمكن أن تظهر المعلومات على خلفية شاشة الساعة على شكل رمز قابل للنقر عليه:
الشكل 1. مؤشر النشاط
يعرض الإشعار المستمر أيضًا معلومات في قسم التطبيقات المستخدَمة مؤخرًا ضمن مشغّل التطبيقات الشامل. ويوفّر ذلك مكانًا آخر مناسبًا للمستخدمين للاطّلاع على حالة مهمتهم وإعادة التفاعل مع التطبيق:
الشكل 2. مشغّل التطبيقات العالمي
في ما يلي بعض الحالات التي يكون فيها من المناسب استخدام إشعار مستمر مرتبط بنشاط مستمر:
الشكل 3. الموقّت: يتم احتساب الوقت بشكل نشط ويتم إيقافه مؤقتًا أو إيقافه نهائيًا.
الشكل 4. التنقّل خطوة بخطوة: تعلن هذه الميزة عن الاتّجاهات المؤدية إلى وجهة معيّنة. تنتهي عندما يصل المستخدم إلى الوجهة أو يتوقّف عن التنقّل.
الشكل 5. الوسائط: تشغيل الموسيقى طوال الجلسة تنتهي الجلسة فورًا بعد أن يوقفها المستخدم مؤقتًا.
ينشئ Wear الأنشطة المستمرة تلقائيًا لتطبيقات الوسائط.
يمكنك الاطّلاع على التجربة العملية حول "النشاط الجاري" للحصول على مثال مفصّل حول كيفية إنشاء أنشطة جارية لأنواع أخرى من التطبيقات.
ضبط إعدادات الميزة
لبدء استخدام واجهة برمجة التطبيقات Ongoing Activity API في تطبيقك، أضِف التبعيات التالية إلى ملف build.gradle
في تطبيقك:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.17.0"
}
إنشاء نشاط مستمر
تتضمّن العملية ثلاث خطوات:
- أنشئ
NotificationCompat.Builder
عادية واضبطها على أن تكون مستمرة. - أنشئ كائن
OngoingActivity
واضبطه، مع تمرير أداة إنشاء الإشعارات إليه. - طبِّق النشاط الجاري على أداة إنشاء الإشعارات وانشر الإشعار الناتج.
إنشاء الإشعار وضبطه
ابدأ بإنشاء NotificationCompat.Builder
. الخطوة الأساسية هي استدعاء
setOngoing(true)
لتصنيفها كإشعار جارٍ. يمكنك أيضًا ضبط خصائص أخرى للإشعارات في هذه المرحلة، مثل الرمز الصغير والفئة.
// Create a PendingIntent to pass to the notification builder val pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, AlwaysOnActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_SINGLE_TOP }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Always On Service") .setContentText("Service is running in background") .setSmallIcon(R.drawable.animated_walk) // Category helps the system prioritize the ongoing activity .setCategory(NotificationCompat.CATEGORY_WORKOUT) .setContentIntent(pendingIntent) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setOngoing(true) // Important!
إنشاء OngoingActivity
بعد ذلك، أنشِئ مثيلاً من OngoingActivity
باستخدام أداة الإنشاء الخاصة به. يتطلّب
OngoingActivity.Builder
Context
ومعرّف إشعار وNotificationCompat.Builder
الذي أنشأته في الخطوة السابقة.
اضبط خصائص المفتاح التي سيتم عرضها على مساحات العرض الجديدة في واجهة المستخدم:
- الرموز المتحركة والثابتة: قدِّم رموزًا يتم عرضها على خلفية شاشة الساعة في الوضعين النشط والمحيط.
- نية اللمس: هي
PendingIntent
تعيد المستخدم إلى تطبيقك عندما ينقر على رمز النشاط الجاري. يمكنك إعادة استخدامpendingIndent
الذي تم إنشاؤه في الخطوة السابقة.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // Sets the icon that appears on the watch face in active mode. .setAnimatedIcon(R.drawable.animated_walk) // Sets the icon that appears on the watch face in ambient mode. .setStaticIcon(R.drawable.ic_walk) // Sets the tap target to bring the user back to the app. .setTouchIntent(pendingIntent) .build()
تطبيقها على الإشعار والمنشور
الخطوة الأخيرة هي ربط OngoingActivity
بالإشعار ثم نشره. تعدّل الطريقة ongoingActivity.apply()
أداة إنشاء الإشعارات الأصلية، وتضيف البيانات اللازمة ليتمكّن النظام من عرضها على المساحات الإضافية. بعد تطبيقها، يمكنك إنشاء الإشعار ونشره كالمعتاد.
// This call modifies notificationBuilder to include the ongoing activity data. ongoingActivity.apply(applicationContext) // Post the notification. startForeground(NOTIFICATION_ID, notificationBuilder.build())
إضافة نص حالة ديناميكي إلى مشغّل التطبيقات
يضيف الرمز السابق الرمز القابل للنقر إلى خلفية الساعة. لتقديم إشعارات أكثر تفصيلاً وفي الوقت الفعلي في قسم الأحداث الأخيرة في مشغّل التطبيقات، أنشئ عنصر Status
وأرفِقه بـ OngoingActivity
. في حال عدم توفير Status
مخصّص، سيستخدم النظام تلقائيًا نص محتوى الإشعار (الذي تم ضبطه باستخدام setContentText()
).
لعرض نص ديناميكي، استخدِم Status.Builder
. يمكنك تحديد سلسلة نموذجية تتضمّن عناصر نائبة وتوفير Status.Part
عناصر لملء هذه العناصر النائبة. يمكن أن يكون Status.Part
ديناميكيًا، مثل ساعة توقيت أو مؤقت .
يوضّح المثال التالي كيفية إنشاء حالة تعرض "الركض لمدة [a stopwatch timer]":
// Define a template with placeholders for the activity type and the timer. val statusTemplate = "#type# for #time#" // Set the start time for a stopwatch. // Use SystemClock.elapsedRealtime() for time-based parts. val runStartTime = SystemClock.elapsedRealtime() val ongoingActivityStatus = Status.Builder() // Sets the template string. .addTemplate(statusTemplate) // Fills the #type# placeholder with a static text part. .addPart("type", Status.TextPart("Run")) // Fills the #time# placeholder with a stopwatch part. .addPart("time", Status.StopwatchPart(runStartTime)) .build()
أخيرًا، اربط هذا الرقم Status
بحسابك OngoingActivity
من خلال الاتصال بالرقم setStatus()
على OngoingActivity.Builder
.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // Add the status to the OngoingActivity. .setStatus(ongoingActivityStatus) .build()
عمليات التخصيص الإضافية
بالإضافة إلى Status
، يمكنك تخصيص نشاطك المستمر أو إشعاراتك بالطرق التالية. ومع ذلك، قد لا يتم استخدام هذه التخصيصات استنادًا إلى طريقة تنفيذ الشركة المصنّعة للمعدات الأصلية.
الإشعار الجاري
- تحدّد فئة النشاط الجاري الأولوية التي يحظى بها.
CATEGORY_CALL
: مكالمة صوتية أو مكالمة فيديو واردة أو طلب مماثل للتواصل بشكل متزامنCATEGORY_NAVIGATION
: خريطة أو اتجاهات مفصّلةCATEGORY_TRANSPORT
: عنصر التحكّم في نقل الوسائط لتشغيلهاCATEGORY_ALARM
: منبّه أو موقّتCATEGORY_WORKOUT
: تمرينCATEGORY_LOCATION_SHARING
: مشاركة الموقع الجغرافي المؤقت الفئة)CATEGORY_STOPWATCH
: ساعة الإيقاف
النشاط الجاري
رمز متحرك: صورة متجهة بالأبيض والأسود، ويُفضّل أن تكون الخلفية شفافة يظهر على خلفية شاشة الساعة في وضع النشاط. في حال عدم توفير الرمز المتحرّك، سيتم استخدام رمز الإشعارات التلقائي. تختلف أيقونة الإشعارات التلقائية من تطبيق إلى آخر.
الرمز الثابت: هو رمز متّجه بخلفية شفافة. يتم عرضها على خلفية شاشة الساعة في وضع عدم النشاط. في حال عدم ضبط الرمز المتحرّك، سيتم استخدام الرمز الثابت على خلفية شاشة الساعة في الوضع النشط. في حال عدم توفيرها، سيتم استخدام رمز الإشعار. إذا لم يتم ضبط أي منهما، سيتم عرض استثناء. (سيظل مشغّل التطبيقات يستخدم رمز التطبيق).
OngoingActivityStatus: نص عادي أو
Chronometer
يظهر في قسم التطبيقات الحديثة في مشغّل التطبيقات. في حال عدم توفيرها، يتم استخدام "نص السياق" للإشعار.نية اللمس: هي
PendingIntent
تُستخدَم للرجوع إلى التطبيق إذا نقر المستخدم على رمز النشاط الجاري. يظهر على خلفية شاشة الساعة أو على رمز التطبيق في مشغّل التطبيقات. يمكن أن يختلف هذا الغرض عن الغرض الأصلي المستخدَم لتشغيل التطبيق. وفي حال عدم توفيره، يتم استخدام غرض المحتوى الخاص بالإشعار. إذا لم يتم ضبط أي منهما، سيتم عرض استثناء.
LocusId
: معرّف يحدّد اختصار مشغّل التطبيقات الذي يتوافق مع النشاط الجاري. يظهر في مشغّل التطبيقات ضمن قسم عمليات البحث الأخيرة أثناء استمرار النشاط. في حال عدم توفيرها، يخفي مشغّل التطبيقات جميع عناصر التطبيق في قسم النشاطات الأخيرة من الحزمة نفسها، ويعرض النشاط الجاري فقط.معرّف النشاط الجاري: هو المعرّف المستخدَم لتمييز طلبات البيانات إلى
fromExistingOngoingActivity()
عندما يكون لدى التطبيق أكثر من نشاط جارٍ واحد.
تعديل نشاط مستمر
في معظم الحالات، ينشئ المطوّرون إشعارًا جديدًا مستمرًا ونشاطًا جديدًا مستمرًا عندما يحتاجون إلى تعديل البيانات على الشاشة. ومع ذلك، توفّر واجهة برمجة التطبيقات OngoingActivity أيضًا طرقًا مساعدة لتعديل OngoingActivity
إذا أردت الاحتفاظ بنسخة بدلاً من إعادة إنشائها.
إذا كان التطبيق يعمل في الخلفية، يمكنه إرسال تحديثات إلى واجهة برمجة التطبيقات Ongoing Activity API. ومع ذلك، لا تُجرِ هذا التعديل بشكل متكرر جدًا، لأنّ طريقة التعديل تتجاهل الطلبات التي تكون متقاربة جدًا من بعضها. ويُعدّ إجراء بضعة تعديلات في الدقيقة أمرًا معقولاً.
لتعديل النشاط الجاري والإشعار الذي تم نشره، استخدِم العنصر الذي أنشأته سابقًا واستدعِ update()
، كما هو موضّح في المثال التالي:
ongoingActivity.update(context, newStatus)
لتسهيل الأمر، يتوفّر إجراء ثابت لإنشاء نشاط جارٍ.
OngoingActivity.recoverOngoingActivity(context)
.update(context, newStatus)
إيقاف نشاط جارٍ
عندما ينتهي التطبيق من العمل كنشاط مستمر، ما عليه سوى إلغاء الإشعار المستمر.
يمكنك أيضًا اختيار إلغاء الإشعار أو النشاط الجاري عند ظهورهما في المقدّمة، ثم إعادة إنشائهما عند الرجوع إلى الخلفية، ولكن هذا ليس مطلوبًا.
إيقاف نشاط جارٍ مؤقتًا
إذا كان تطبيقك يتضمّن إجراء إيقاف مؤقت صريحًا، واصِل النشاط الجاري بعد إزالة الإيقاف المؤقت. بالنسبة إلى تطبيق لا يتضمّن إجراء إيقاف صريحًا، يجب إنهاء النشاط عند إيقافه مؤقتًا.
أفضل الممارسات
يُرجى تذكُّر ما يلي عند استخدام واجهة برمجة التطبيقات Ongoing Activity API:
اضبط رمزًا ثابتًا لـ "النشاط قيد التقدّم"، إما بشكل صريح أو كبديل باستخدام الإشعار. إذا لم يكن لديك، ستظهر لك
IllegalArgumentException
.استخدِم رموزًا متجهة باللونين الأبيض والأسود مع خلفيات شفافة.
اضبط نية اللمس لنشاطك الجاري، إما بشكل صريح أو كإجراء احتياطي باستخدام الإشعار. إذا لم يكن لديك، ستظهر لك
IllegalArgumentException
.إذا كان تطبيقك يتضمّن أكثر من نشاط واحد
MAIN LAUNCHER
تم تحديده في ملف البيان، عليك نشر اختصار ديناميكي وربطه بنشاطك الجاري باستخدامLocusId
.
نشر إشعارات الوسائط عند تشغيل الوسائط على أجهزة Wear OS
إذا كان يتم تشغيل محتوى وسائط على جهاز Wear OS، انشر إشعارًا بالوسائط. يتيح ذلك للنظام إنشاء النشاط الجاري المقابل.
إذا كنت تستخدم Media3، سيتم نشر الإشعار تلقائيًا. إذا أنشأت الإشعار يدويًا، يجب أن يستخدم MediaStyleNotificationHelper.MediaStyle
، ويجب أن يتم ملء نشاط الجلسة في MediaSession
المقابل.
اقتراحات مخصصة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون JavaScript غير مفعّلة
- إنشاء إشعار {:#notification}
- التفاعل مع مستخدمي Wear OS بطرق جديدة باستخدام Ongoing Activity API
- إنشاء إشعار قابل للتوسعة {:#expandable-notification}