نمایش فعالیت‌های جاری

دستگاه‌های Wear OS اغلب برای تجربه‌های طولانی‌مدت، مانند ردیابی تمرین ورزشی، استفاده می‌شوند. این تجربه‌ها همچنین ممکن است اطلاعات مهمی را که کاربر به آن‌ها اهمیت می‌دهد و نیاز دارد به آن‌ها دسترسی سریع داشته باشد ارائه دهند.

این امر چالش تجربه کاربری ایجاد می‌کند: اگر کاربری کاری را شروع کند و سپس به صفحه ساعت برود، باید همچنان بتواند هریک از موارد زیر را انجام دهد:

  • به دریافت به‌روزرسانی‌های مهم ادامه دهید.
  • با یک تک‌ضرب به تکلیف برگردید.

بازگشت به برنامه بااستفاده از راه‌انداز می‌تواند دشوار باشد، به‌ویژه درحال حرکت، و اصطکاک غیرضروری ایجاد می‌کند.

از Wear OS 7، راهکار این است که اعلان جاری را با OngoingActivity یا اعلان «به‌روزرسانی زنده» جفت کنید. این کار به دستگاه امکان می‌دهد اطلاعات مربوط به فعالیت طولانی‌مدت را در سراسر واسط کاربر نمایش دهد و ویژگی‌هایی مثل نماد ضربه‌زدنی در پایین صفحه ساعت را فعال کند. این نشانگر کاربران را از وظیفه پس‌زمینه‌ای مطلع می‌کند و روشی یک‌ضرب برای بازگشت به برنامه ارائه می‌دهد.

فعالیت جاری یا «به‌روزرسانی زنده» نیز باعث می‌شود برنامه شما برای مدت طولانی‌تری قابل‌مشاهده باشد و از بازگشت سیستم به صفحه ساعت پس‌از مدتی عدم فعالیت جلوگیری می‌کند. برای اطلاعات بیشتر، به نمایان نگه داشتن برنامه در Wear مراجعه کنید.

از فعالیت جاری یا اعلان به‌روزرسانی زنده برای تجربه‌هایی که احتمالاً بیشتر از یک دقیقه طول می‌کشند یا در مواردی که احتمالاً کاربر قبل‌از تکمیل تکلیف از برنامه شما خارج می‌شود استفاده کنید.

کاربردهای مناسب: تمرین‌های ورزشی ردیابی‌شده؛ زمان‌سنج‌ها؛ ردیابی فعال هم‌سفری؛ ضبط صدای طولانی‌تر، مثل جلسه؛ و فهرست‌های خرید که باید درحالی‌که کاربر در فروشگاه است دردسترس باشند

استفاده‌های نامناسب: ضبط پیام‌های صوتی کوتاه، تبلیغات، وضعیت برنامه درحال به‌روزرسانی، و رویدادهای آتی تقویم.

مهم: استفاده از OngoingActivity یا به‌روزرسانی زنده در این سناریوها براساس دستورالعمل‌های کیفیت برنامه Wear OS WO-V4 الزامی است.

برای مثال، در این برنامه تمرین، اطلاعات می‌تواند در صفحه ساعت کاربر به‌صورت نماد دویدن لمس‌کردنی نشان داده شود:

نماد درحال اجرا

شکل ۱. نشانگر فعالیت.

اعلان جاری همچنین اطلاعات را در بخش موارد اخیر راه‌انداز برنامه جهانی نمایش می‌دهد. این کار مکان مناسب دیگری را برای کاربران فراهم می‌کند تا وضعیت تکلیفشان را ببینند و دوباره با برنامه تعامل برقرار کنند:

راه‌انداز

شکل ۲. راه‌انداز جهانی.

موقعیت‌های زیر برای استفاده از اعلان جاری مرتبط با «فعالیت جاری» مناسب است:

زمان‌سنج

شکل ۳. زمان‌سنج: زمان را به‌صورت فعال شمارش معکوس می‌کند و وقتی زمان‌سنج موقت یا متوقف می‌شود پایان می‌یابد.

نقشه

شکل ۴. ناوبری گام‌به‌گام: مسیرهای رسیدن به مقصد را اعلام می‌کند. وقتی کاربر به مقصد می‌رسد یا پیمایش را متوقف می‌کند، پایان می‌یابد.

موسیقی

شکل ۵. رسانه: موسیقی را در طول جلسه پخش می‌کند. بلافاصله پس‌از اینکه کاربر جلسه را موقتاً متوقف می‌کند پایان می‌یابد.

‫Wear به‌طور خودکار «فعالیت‌های جاری» را برای برنامه‌های رسانه ایجاد می‌کند.

برای نمونه‌ای جامع از ایجاد «فعالیت‌های درحال انجام» برای انواع دیگر برنامه‌ها، به codelab «فعالیت درحال انجام» مراجعه کنید.

راه‌اندازی

برای شروع استفاده از «میانای برنامه‌سازی کاربردی فعالیت جاری» در برنامه‌تان، وابستگی‌های زیر را به فایل build.gradle برنامه‌تان اضافه کنید:

dependencies {
  implementation "androidx.wear:wear-ongoing:1.1.0"
  implementation "androidx.core:core:1.19.1"
}

ایجاد فعالیت جاری

این فرایند شامل سه مرحله است:

  1. NotificationCompat.Builder استاندارد ایجاد کنید و آن را به‌عنوان ادامه‌دار پیکربندی کنید.
  2. شیء OngoingActivity را ایجاد و پیکربندی کنید و سازنده اعلان را به آن ارسال کنید.
  3. «فعالیت جاری» را در سازنده اعلان اعمال کنید و اعلان حاصل را پست کنید.

ایجاد و پیکربندی اعلان

با ایجاد یک 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 می‌تواند پویا باشد، مثل وقت‌نگهدار یا زمان‌سنج.

مثال زیر نشان می‌دهد که چگونه وضعیتی ایجاد کنید که «دویدن برای [زمان‌سنج کرونومتر]» را نمایش دهد:

// 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()

در آخر، با شماره setStatus() در OngoingActivity.Builder تماس بگیرید و این Status را به OngoingActivity پیوند دهید.

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() وقتی برنامه‌ای بیش‌از یک فعالیت جاری دارد.

به‌روزرسانی «فعالیت جاری»

وقتی نیاز دارید وضعیت را تغییر دهید، باید «فعالیت جاری» را برای اعلان موجود به‌روز کنید، نه اینکه اعلان و «فعالیت جاری» جدیدی ایجاد کنید. برای به‌روزرسانی «فعالیت جاری» و اعلان پست‌شده، از شیئی که قبلاً ساخته‌اید استفاده کنید و update() را فراخوانی کنید، همان‌طور که در مثال زیر نشان داده شده است:

ongoingActivity.update(context, newStatus)

در مواردی که ذخیره کردن مرجع برای Ongoing Activity امکان‌پذیر نیست، روش ایستایی برای بازیابی Ongoing Activity وجود دارد. بااین‌حال، این مورد کمتر ترجیح داده می‌شود:

OngoingActivity.recoverOngoingActivity(context)
    ?.update(context, newStatus)

توقف فعالیت جاری

وقتی برنامه به‌عنوان «فعالیت جاری» اجرا می‌شود، فقط باید اعلان جاری را لغو کند.

همچنین می‌توانید انتخاب کنید که وقتی اعلان یا «فعالیت جاری» به پیش‌زمینه می‌آید، آن را لغو کنید و سپس وقتی به پس‌زمینه برمی‌گردد، آن‌ها را دوباره ایجاد کنید، اما این کار الزامی نیست.

توقف موقت «فعالیت درحال انجام»

اگر برنامه شما کنش توقف صریحی دارد، «فعالیت جاری» را پس‌از ازسر گرفته شدن ادامه دهید. برای برنامه‌ای که کنش توقف صریحی ندارد، فعالیت را وقتی متوقف می‌شود پایان دهید.

ملاحظات کلیدی

هنگام کار با Ongoing Activity API، موارد زیر را به‌خاطر داشته باشید:

  • نماد ثابتی برای «فعالیت جاری» خود تنظیم کنید، یا صریحاً یا به‌عنوان جایگزین بااستفاده از اعلان. اگر این کار را نکنید، IllegalArgumentException دریافت می‌کنید.

  • از نمادهای برداری سیاه‌وسفید با پس‌زمینه‌های شفاف استفاده کنید.

  • هدف لمس را برای «فعالیت جاری» خود، یا صریحاً یا به‌عنوان یک جایگزین بااستفاده از اعلان تنظیم کنید. اگر این کار را نکنید، IllegalArgumentException دریافت می‌کنید.

  • اگر برنامه شما بیش‌از یک MAIN LAUNCHER فعالیت در مانیفست اعلام‌شده دارد، میان‌بر پویا منتشر کنید و آن را با «فعالیت جاری» خود بااستفاده از LocusId مرتبط کنید.

هنگام پخش رسانه در دستگاه‌های Wear OS، اعلان رسانه منتشر می‌شود

اگر محتوای رسانه‌ای در دستگاه Wear OS درحال پخش است، اعلان رسانه منتشر کنید. این کار به سیستم اجازه می‌دهد فعالیت جاری مربوطه را ایجاد کند.

اگر از Media3 استفاده می‌کنید، اعلان به‌طور خودکار منتشر می‌شود. اگر اعلان را به‌صورت دستی ایجاد می‌کنید، باید از MediaStyleNotificationHelper.MediaStyle استفاده کند و MediaSession مربوطه باید فعالیت جلسه آن تکمیل شده باشد.