فعالیت های در حال انجام

دستگاه‌های Wear OS اغلب برای تجربیات طولانی مدت، مانند ردیابی یک تمرین، استفاده می‌شوند. این یک چالش تجربه کاربری را ایجاد می‌کند: اگر کاربر کاری را شروع کند و سپس به صفحه ساعت برود، چگونه می‌تواند به آن برگردد؟ بازگشت به برنامه با استفاده از لانچر می‌تواند دشوار باشد، به خصوص هنگام حرکت، که باعث ایجاد اصطکاک غیرضروری می‌شود.

راه حل این است که یک اعلان مداوم را با یک OngoingActivity جفت کنید. این به دستگاه اجازه می‌دهد تا اطلاعات مربوط به فعالیت طولانی مدت را در رابط کاربری نمایش دهد و ویژگی‌هایی مانند نماد قابل لمس در پایین صفحه ساعت را فعال کند. این کار کاربران را از وظیفه پس‌زمینه آگاه نگه می‌دارد و راهی برای بازگشت به برنامه با یک لمس فراهم می‌کند.

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

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

آیکون در حال اجرا

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

یک اعلان مداوم همچنین اطلاعاتی را در بخش «اخیر» (Recents ) لانچر سراسری برنامه نمایش می‌دهد. این مکان مناسب دیگری را برای کاربران فراهم می‌کند تا وضعیت وظیفه خود را ببینند و دوباره با برنامه تعامل کنند:

پرتابگر

شکل ۲. لانچر سراسری.

موارد زیر موقعیت‌های خوبی برای استفاده از اعلان‌های مداوم مرتبط با یک فعالیت مداوم هستند:

تایمر

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

نقشه

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

موسیقی

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

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

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

راه‌اندازی

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

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

ایجاد یک فعالیت مداوم

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

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

متن وضعیت پویا را به لانچر اضافه کنید

کد قبلی، آیکون قابل لمس را به صفحه ساعت اضافه می‌کند. برای ارائه به‌روزرسانی‌های غنی‌تر و بلادرنگ در بخش Recents لانچر، یک شیء 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 ، می‌توانید فعالیت‌ها یا اعلان‌های جاری خود را به روش‌های زیر سفارشی کنید. با این حال، ممکن است این سفارشی‌سازی‌ها بر اساس پیاده‌سازی OEM مورد استفاده قرار نگیرند.

اطلاع رسانی مداوم

  • مجموعه دسته‌بندی ، اولویت فعالیت جاری را تعیین می‌کند.
    • CATEGORY_CALL : یک تماس صوتی یا تصویری ورودی یا یک درخواست ارتباط همزمان مشابه
    • CATEGORY_NAVIGATION : یک نقشه یا ناوبری گام به گام
    • CATEGORY_TRANSPORT : کنترل انتقال رسانه برای پخش
    • CATEGORY_ALARM : یک زنگ هشدار یا تایمر
    • CATEGORY_WORKOUT : یک تمرین
    • CATEGORY_LOCATION_SHARING : دسته اشتراک‌گذاری موقت مکان
    • CATEGORY_STOPWATCH : کرونومتر

فعالیت مداوم

  • آیکون متحرک: یک بردار سیاه و سفید، ترجیحاً با پس‌زمینه شفاف. در حالت فعال روی صفحه ساعت نمایش داده می‌شود. اگر آیکون متحرک ارائه نشود، از آیکون اعلان پیش‌فرض استفاده می‌شود. آیکون اعلان پیش‌فرض برای هر برنامه متفاوت است.

  • آیکون ثابت: یک آیکون برداری با پس‌زمینه شفاف. در حالت محیطی روی صفحه ساعت نمایش داده می‌شود. اگر آیکون متحرک تنظیم نشده باشد، در حالت فعال از آیکون ثابت روی صفحه ساعت استفاده می‌شود. اگر این گزینه ارائه نشود، از آیکون اعلان استفاده می‌شود. اگر هیچ‌کدام تنظیم نشده باشند، یک استثنا ایجاد می‌شود. (لانچر برنامه همچنان از آیکون برنامه استفاده می‌کند.)

  • وضعیت فعالیت جاری: متن ساده یا یک Chronometer . در بخش « آخرین‌ها» ی لانچر برنامه نمایش داده می‌شود. در صورت عدم ارائه، از «متن زمینه» اعلان استفاده می‌شود.

  • هدف لمسی: یک PendingIntent که برای بازگشت به برنامه در صورت لمس آیکون فعالیت جاری توسط کاربر استفاده می‌شود. این هدف در صفحه ساعت یا روی آیتم لانچر نمایش داده می‌شود. این هدف می‌تواند با هدف اصلی مورد استفاده برای راه‌اندازی برنامه متفاوت باشد. در صورت عدم ارائه، از هدف محتوای اعلان استفاده می‌شود. اگر هیچ‌کدام تنظیم نشوند، یک استثنا ایجاد می‌شود.

  • LocusId : شناسه‌ای که میانبر لانچر مربوط به فعالیت جاری را تعیین می‌کند. در حالی که فعالیت در حال انجام است، در لانچر در بخش Recents نمایش داده می‌شود. اگر ارائه نشود، لانچر تمام آیتم‌های برنامه در بخش Recents را از همان بسته پنهان می‌کند و فقط فعالیت جاری را نشان می‌دهد.

  • شناسه فعالیت جاری: شناسه‌ای که برای رفع ابهام از فراخوانی‌های fromExistingOngoingActivity() استفاده می‌شود، زمانی که یک برنامه بیش از یک فعالیت جاری دارد.

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

در بیشتر موارد، توسعه‌دهندگان وقتی نیاز به به‌روزرسانی داده‌ها روی صفحه دارند، یک اعلان مداوم جدید و یک فعالیت مداوم جدید ایجاد می‌کنند. با این حال، اگر می‌خواهید یک نمونه را به جای ایجاد مجدد، حفظ کنید، API مربوط به فعالیت مداوم، متدهای کمکی را نیز برای به‌روزرسانی یک OngoingActivity مداوم ارائه می‌دهد.

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

برای به‌روزرسانی فعالیت جاری و اعلان ارسال‌شده، از شیء‌ای که قبلاً ایجاد کرده‌اید استفاده کنید و تابع update() فراخوانی کنید، همانطور که در مثال زیر نشان داده شده است:

ongoingActivity.update(context, newStatus)

برای راحتی، یک متد استاتیک برای ایجاد یک فعالیت مداوم وجود دارد.

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

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

وقتی اجرای برنامه به عنوان یک فعالیت مداوم به پایان رسید، فقط کافی است اعلان مداوم را لغو کند.

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

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

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

بهترین شیوه‌ها

هنگام کار با API فعالیت در حال انجام، موارد زیر را به خاطر داشته باشید:

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

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

  • برای فعالیت جاری خود، چه به صورت صریح و چه به عنوان یک جایگزین با استفاده از اعلان، یک هدف لمسی تعیین کنید. در غیر این صورت، با IllegalArgumentException مواجه خواهید شد.

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

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

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

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

{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}