استفاده از اعلان‌های اندروید

این کد لبه بخشی از دوره آموزشی Advanced Android in Kotlin است. اگر از طریق کدها به صورت متوالی کار کنید، بیشترین ارزش را از این دوره خواهید گرفت، اما اجباری نیست. همه کدهای دوره در صفحه فرود Android Advanced in Kotlin Codelabs فهرست شده اند.

مقدمه

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

یک اعلان معمولی شامل یک عنوان، یک توضیح و یک نماد است. یک اعلان همچنین می تواند دارای اقدامات قابل کلیک، پاسخ سریع، محتوای قابل تمدید و تصاویر باشد.

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

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

در این کدلب با نحوه ایجاد و استفاده از نوتیفیکیشن در اپلیکیشن اندروید آشنا می شوید.

آنچه از قبل باید بدانید

باید با:

  • چگونه برنامه های اندروید را در کاتلین در جعبه قرار دهیم. به ویژه، با Android SDK کار کنید.
  • نحوه طراحی برنامه ها با استفاده از اجزای معماری و اتصال داده ها.
  • درک اولیه Broadcast Receivers
  • درک اولیه از AlarmManager

چیزی که یاد خواهید گرفت

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

کاری که خواهی کرد

  • یک اعلان به برنامه شروع اضافه کنید.
  • اعلانی را که قبلا ارسال کرده اید لغو کنید.
  • ایجاد کانال برای انواع مختلف اعلان ها.
  • اعلان‌ها را در برنامه شروع سفارشی کنید.
  • اقدامات سریع را اضافه کنید تا اعلان های خود را تعاملی کنید.
  • نشان های اعلان را خاموش کنید.

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

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

در حالت ایده‌آل، تایمر تخم مرغ باید از اعلان‌ها استفاده کند تا به کاربران بگوید زمان تمام شده است. کاربر واقعاً باید بداند که تخم مرغ ها بلافاصله آماده هستند، در غیر این صورت تخم مرغ ها بیش از حد پخته می شوند! اعلان‌ها بصری هستند، می‌توانند شامل صداها باشند و می‌توانند دستگاه را به لرزش درآورند—همه راه‌هایی برای جلب توجه کاربر! به این ترتیب می توانید به تخم مرغ های عالی و کاربرانی شاد و پر تغذیه دست یابید.

برای دریافت نمونه برنامه، می توانید یکی از موارد زیر را انجام دهید:

Repository را از GitHub کلون کنید و به شاخه starter سوئیچ کنید.

$  git clone https://github.com/googlecodelabs/android-kotlin-notifications


یا می توانید مخزن را به صورت یک فایل Zip دانلود کنید، آن را از حالت فشرده خارج کنید و در اندروید استودیو باز کنید.

زیپ را دانلود کنید

  1. برنامه را در اندروید استودیو باز کرده و اجرا کنید.

یک تصویر تخم مرغ و یک منوی کشویی با لیستی از فواصل زمانی از پیش تعریف شده برای پختن تخم مرغ مشاهده خواهید کرد. برای منوی کشویی Soft Boiled روی مثلث کلیک کنید. اولین گزینه در لیست برای اهداف آزمایشی داده شده است و زنگ ساعت را تنها روی 10 ثانیه تنظیم می کند. در کنار لیست یک سوئیچ وجود دارد که تایمر تخم مرغ را شروع می کند. می توانید از این سوئیچ برای شروع و توقف تایمر تخم مرغ در هر زمان که بخواهید استفاده کنید. کد شروع کاملاً کاربردی است، به این معنی که می توانید تایمر تخم مرغ را تنظیم کنید و شمارش معکوس آن را تا 0 تماشا کنید. پس از اتمام تایمر، پیام نان تست مانند شکل زیر نمایش داده می شود.

  1. کد منبع را بررسی کنید. برنامه شروع از یک فعالیت واحد به نام MainActivity تشکیل شده است. سه بسته فرعی به نام‌های receiver ، ui و util وجود دارد.

  • /receiver - بسته receiver شامل دو گیرنده پخش به نام‌های AlarmReceiver و SnoozeReceiver است. AlarmReceiver توسط AlarmManager برای ارسال اعلان زمانی که تایمر تعریف شده توسط کاربر فعال است فعال می شود. SnoozeReceiver کلیک کاربر را برای به تعویق انداختن اعلان کنترل می کند.
  • /ui - این شامل EggTimerFragment است که بخشی از بخش UI برنامه است. EggTimerViewModel مسئول شروع و لغو تایمر و سایر وظایف برنامه مربوط به چرخه حیات است.
  • /util — در این بسته دو فایل وجود دارد. BindingUtils.kt دارای آداپتورهای اتصال برای فعال کردن اتصال داده بین رابط کاربری برنامه و ViewModel است. NotificationUtils.kt دارای متدهای پسوندی در NotificationManager است.

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

مرحله 1: یک اعلان اولیه ایجاد کنید

در این کار، شما در حال ایجاد یک اعلان جدید، تنظیم یک پیام برای کاربر خود و ارسال اعلان هستید.

  1. کلاس NotificationUtils.kt را باز کنید و TODO: Step 1.1 . کارهای منطبق را در این لبه کد و کد برنامه پیدا خواهید کرد.
  2. تابع sendNotification() داده شده را بررسی کنید. برای ارسال اعلان‌ها، این تابع افزونه را به NotificationManager گسترش خواهید داد.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
 * Builds and delivers a notification.
 *
 * @param messageBody, notification text.
 * @param context, activity context.
 */
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
  1. نمونه‌ای از سازنده اعلان دریافت کنید، در زمینه برنامه ارسال کنید و یک شناسه کانال. شناسه کانال یک مقدار رشته ای برای کانال است.

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

//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
        applicationContext,
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. نماد اعلان را برای نمایش برنامه، عنوان و متن محتوای پیامی که می‌خواهید به کاربر بدهید، تنظیم کنید. گزینه‌های بیشتری برای سفارشی‌سازی بیشتر اعلان‌ها در لبه کد خواهید دید، اما این حداقل داده‌ای است که برای ارسال اعلان باید تنظیم کنید.
//NotificationUtils.kt
   // TODO: Step 1.3 set title, text and icon to builder
   .setSmallIcon(R.drawable.cooked_egg)
   .setContentTitle(applicationContext.getString(R.string.notification_title))
   .setContentText(messageBody)
  1. در مرحله بعد، باید notify() را با یک شناسه منحصر به فرد برای اعلان خود و با شی Notification از سازنده خود فراخوانی کنید.

این شناسه نمونه اعلان فعلی را نشان می دهد و برای به روز رسانی یا لغو این اعلان مورد نیاز است. از آنجایی که برنامه شما در یک زمان معین فقط یک اعلان فعال خواهد داشت، می توانید از همان شناسه برای همه اعلان های خود استفاده کنید. قبلاً برای این منظور یک ثابت به نام NOTIFICATION_ID در NotificationUtils.kt به شما داده شده است. توجه داشته باشید که می‌توانید مستقیماً notify() را فراخوانی کنید زیرا در حال انجام تماس از یک تابع افزونه در همان کلاس هستید.

//NotificationUtils.kt
   // TODO: Step 1.4 call notify to send the notification
    // Deliver the notification
    notify(NOTIFICATION_ID, builder.build())
  1. ui/EggTimerViewModel.kt را باز کنید و تابع startTimer() را پیدا کنید. هنگامی که کاربر تایمر تخم مرغ را فعال می کند، این عملکرد یک زنگ هشدار با فاصله زمانی انتخاب شده ایجاد می کند.
  2. هنگامی که کاربر تایمر را شروع می کند، یک اعلان در این عملکرد راه اندازی می کنید. برای فراخوانی تابع sendNotification() که قبلا پیاده سازی کرده اید، به یک نمونه از NotificationManager نیاز دارید. NotificationManager یک سرویس سیستمی است که همه عملکردهای در معرض دید API اعلان‌ها، از جمله عملکرد افزونه‌ای را که اضافه کرده‌اید، ارائه می‌کند. هر زمان که می خواهید اعلانی را ارسال، لغو یا به روز کنید، باید یک نمونه از NotificationManager را از سیستم درخواست کنید. sendNotification()| را فراخوانی کنید با پیام اعلان و با زمینه کار کنید.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification

val notificationManager = ContextCompat.getSystemService(
    app, 
    NotificationManager::class.java
) as NotificationManager
                notificationManager.sendNotification(app.getString(R.string.timer_running), app)

شما تقریباً آنجا هستید. با این حال، اگر اکنون برنامه خود را اجرا کنید و تایمر را تنظیم کنید، اعلانی دریافت نخواهید کرد.

  1. logcat را باز کنید و "No Channel found" را جستجو کنید. باید یک پیغام خطایی ببینید که egg_channel وجود ندارد. در مراحل زیر در مورد کانال های اعلان بیشتر خواهید آموخت و این مشکل را برطرف خواهید کرد.

مرحله 2: کانال های اطلاع رسانی

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

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

برنامه نویسان تنظیمات اولیه، اهمیت و رفتار را تنظیم می کنند تا برای همه اعلان های یک کانال اعمال شود. پس از تنظیم تنظیمات اولیه، کاربران می توانند این تنظیمات را لغو کنند.

در مرحله 1.1 از egg_notification_channel_id به عنوان کانال اعلان خود استفاده کردید، بنابراین اکنون باید تنظیمات و رفتار اعلان این کانال را ایجاد و سفارشی کنید.

  1. EggTimerFragment.kt را باز کنید و تابع createChannel() را پیدا کنید.
  2. شناسه منحصر به فرد کانال را به سازنده NotificationChannel ارسال کنید.
  3. نام کانال اعلان را ارسال کنید، که کاربران در صفحه تنظیمات خود نیز مشاهده خواهند کرد.
  4. به عنوان آخرین پارامتر، سطح اهمیت را برای کانال اطلاع رسانی ارسال کنید. سطوح اهمیت بعداً در این آزمایشگاه کد پوشش داده خواهد شد، بنابراین در حال حاضر می توانید از NotificationManag er.IMPORTANCE_LOW استفاده کنید.
  5. در شیء notificationChannel ، enableLights را روی true تنظیم کنید. این تنظیم هنگام نمایش اعلان، چراغ ها را فعال می کند.
  6. در شیء notificationChannel ، lightColor را روی قرمز تنظیم کنید تا هنگام نمایش اعلان، چراغ قرمز نمایش داده شود.
  7. در شیء notificationChannel برای فعال کردن لرزش، enableVibration را روی true تنظیم کنید.
  8. در شیء notificationChannel ، توضیحات کانال را روی 'Time for breakf » تنظیم کنید.
  9. با فراخوانی getSystemService() نمونه ای از NotificationManager را دریافت کنید.
  10. createNotificationChannel() را در NotificationManager فراخوانی کنید و شی notificationChannel را که در مرحله قبل ایجاد کردید ارسال کنید.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
    // TODO: Step 1.6 START create a channel
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationChannel = NotificationChannel(
            channelId,
            channelName,
            // TODO: Step 2.4 change importance
            NotificationManager.IMPORTANCE_LOW
        )
        // TODO: Step 2.6 disable badges for this channel

        notificationChannel.enableLights(true)
        notificationChannel.lightColor = Color.RED
        notificationChannel.enableVibration(true)
        notificationChannel.description = "Time for breakfast"

        val notificationManager = requireActivity().getSystemService(
            NotificationManager::class.java
        )
        notificationManager.createNotificationChannel(notificationChannel)
    }
    // TODO: Step 1.6 END create channel
}
  1. در مرحله بعد، برای ایجاد یک کانال، باید تابع createChannel() را که نوشتید فراخوانی کنید (مرحله 1.7). این تابع دو پارامتر دارد، شناسه کانال و نام کانال. باید شناسه کانال و نام کانال خود را از منابع رشته ای که قبلاً در پروژه شما داده شده است جستجو کنید.
// EggTimerFragment.kt
    // TODO: Step 1.7 call createChannel
    createChannel(
          getString(R.string.egg_notification_channel_id),
          getString(R.string.egg_notification_channel_name)
    )
  1. باید شناسه کانال را به سازنده اعلان ارسال کنید. شما قبلاً این کار را در مرحله 1.2 انجام دادید. تنظیم یک مقدار اشتباه به عنوان شناسه کانال باعث می شود اعلان ناموفق باشد. برای تأیید صحت شناسه کانالی که قبلاً تنظیم کرده اید، NotificationUtils.kt را باز کنید.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
        applicationContext,
       // TODO: Step 1.8 verify the notification channel name
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. برنامه را اجرا کنید، و خواهید دید که هر بار که تایمر را شروع می کنید، برنامه یک اعلان ارسال می کند.
  2. نوار وضعیت را بکشید و توجه کنید که عنوان اعلان، محتوا و نماد همانطور که در مراحل قبل تنظیم کردید هستند.
  3. برای تأیید کانال جدید ایجاد شده، برنامه را ببندید و نماد برنامه را پیدا کنید. یک ضربه طولانی روی نماد برنامه انجام دهید و اطلاعات برنامه را انتخاب کنید.

  1. اعلان ها را از لیست تنظیمات انتخاب کنید. باید کانال جدیدی به نام Egg را دقیقاً زیر تنظیمات نمایش اعلان‌ها ببینید.

هنگامی که برنامه را اجرا می کنید، اعلان اکنون نشان داده می شود. هم شما به عنوان توسعه‌دهنده برنامه و هم کاربرانتان می‌توانید تنظیمات و رفتار را برای همه اعلان‌های ارسال شده در این کانال سفارشی کنید. تبریک، شما یک اعلان ایجاد کردید!

مرحله 3: اعلان ها را به برنامه خود اضافه کنید

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

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

برنامه شما از AlarmManager برای تنظیم زنگ هشدار استفاده می کند. کد مربوط به AlarmManager قبلاً در کد شروع داده شده است و برای نمایش پیام نان تست استفاده می شود. AlarmManager انتخاب زمان مورد نظر را ردیابی می کند و پس از اتمام زمان، تابع onReceive() AlarmReceiver.kt را فعال می کند. اگر AlarmReceiver.kt را باز کنید و به onReceive() بروید، باید پیام نان تست را ببینید که هر بار که یک تایمر تخم مرغ را تنظیم می کنید نمایش داده می شود.

  1. AlarmReceiver.kt باز کنید، یک نمونه از NotificationManager ، و تابع sendNotification() را با پارامترهای متن پیام و متن فراخوانی کنید.
// AlarmReceiver.kt
   // TODO: Step 1.9 add call to sendNotification
   val notificationManager = ContextCompat.getSystemService(
       context, 
       NotificationManager::class.java
   ) as NotificationManager
             
   notificationManager.sendNotification(
       context.getText(R.string.eggs_ready).toString(), 
       context
   )
  1. به صورت اختیاری، نان تست را بردارید زیرا برنامه شما با اتمام تایمر اعلان ارسال می کند.
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. برنامه خود را اجرا کنید. هر بار که تایمر را راه اندازی می کنید و هر بار که تایمر روشن است، باید یک اعلان ببینید.

این ایده آل نیست شما نمی خواهید اعلان های زیادی برای کاربران خود ارسال کنید. می توانید اولین اعلانی را که هنگام شروع تایمر توسط کاربر ارسال می شود حذف کنید.

  1. EggTimerFragment.kt را باز کنید و کد اعلان مرحله 1.5 را حذف کنید.
// EggTimeViewModel.kt

// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
//      app,
//      NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
  1. دوباره برنامه خود را اجرا کنید.
  2. یک تایمر تنظیم کنید، آن را در پس زمینه قرار دهید و منتظر بمانید تا زمان تمام شود. یک اعلان خواهید دید. این یک اعلان بسیار مفیدتر است.

مرحله 4: یک هدف محتوا اضافه کنید

  1. اگر برنامه از قبل اجرا نشده است، دوباره آن را اجرا کنید.
  2. روی اعلان کلیک کنید. هیچ اتفاقی نمی افتد!

نمایش اعلان و اطلاع رسانی به کاربر عالی است، اما وقتی کاربر روی یک اعلان کلیک می کند، انتظار دارد به برنامه مربوطه برگردد. در این قسمت از Codelab یک هدف به اعلان خود اضافه می کنید تا کاربر را به صفحه تایمر بازگرداند.

Intent یک شیء پیام رسانی است که می توانید از آن برای درخواست یک عمل از مؤلفه برنامه دیگر استفاده کنید. Intent ها می توانند برای شروع یک فعالیت، یک سرویس یا ارائه یک پخش استفاده شوند. در این حالت، از این قصد استفاده می‌کنید تا به سیستم بگویید که وقتی کاربر روی اعلان ضربه می‌زند، MainActivity را باز کند. از آنجایی که برنامه شما فقط از یک نمای واحد تشکیل شده است، گزینه های زیادی در اینجا ندارید. با این حال، در یک برنامه بزرگتر، اعلان باید با آوردن کاربر به صفحه ای که برای زمانی که با اعلان تعامل دارد، یک تجربه یکپارچه ایجاد کند.

  1. NotificationUtils.kt را باز کنید و تابع پسوند sendNotification() را پیدا کنید.
  2. یک Intent با applicationContext و فعالیتی که قرار است راه اندازی شود، MainActivity::class.java کنید.
// NotificationUtils.kt

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
    // Create the content intent for the notification, which launches
    // this activity
   // TODO: Step 1.11 create intent
    val contentIntent = Intent(applicationContext, MainActivity::class.java)

شما قصد ایجاد کرده اید، اما اعلان خارج از برنامه شما نمایش داده می شود. برای اینکه یک intent خارج از برنامه شما کار کند، باید یک PendingIntent جدید ایجاد کنید.

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

  1. یک PendingIntent با applicationContext ، NOTIFICATION_ID ، contentIntent که در مرحله قبل ایجاد کردید و پرچم PendingIntent ایجاد کنید. پرچم PendingIntent گزینه ای را برای ایجاد یک PendingIntent جدید یا استفاده از یک موجود مشخص می کند. شما باید PendingIntent.FLAG_UPDATE_CURRENT را به عنوان پرچم تنظیم کنید زیرا نمی‌خواهید در صورت وجود اعلان جدید، اعلان جدیدی ایجاد کنید. به این ترتیب شما PendingIntent فعلی را که با هدفی که ارائه می کنید مرتبط است، تغییر می دهید.
// NotificationUtils.kt
   // TODO: Step 1.12 create PendingIntent
    val contentPendingIntent = PendingIntent.getActivity(
        applicationContext, 
        NOTIFICATION_ID,
        contentIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )
  1. PendingIntent را به اعلان خود منتقل کنید. این کار را با فراخوانی setContentIntent() در NotificationBuilder انجام می دهید. اکنون، وقتی روی اعلان کلیک می‌کنید، PendingIntent و MainActivity شما باز می‌شود.
  2. همچنین setAutoCancel() را روی true قرار دهید، به طوری که وقتی کاربر روی اعلان ضربه می زند، اعلان خود را نادیده می گیرد زیرا آنها را به برنامه می برد.
// NotificationUtils.kt
    // TODO: Step 1.13 set content intent
    .setContentIntent(contentPendingIntent)
    .setAutoCancel(true)
  1. دوباره برنامه را اجرا کنید.
  2. یک تایمر تنظیم کنید، برنامه را در پس زمینه قرار دهید و منتظر بمانید تا اعلان ظاهر شود.
  3. هنگامی که اعلان را مشاهده کردید، با پایین کشیدن نوار وضعیت، روی اعلان کلیک کنید و مشاهده کنید که چگونه برنامه در پیش زمینه قرار می گیرد.

مرحله 5: اعلان را لغو کنید

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

برای رفع این مشکل، باید هنگام شروع تایمر جدید، اعلان قبلی را پاک کنید. با ایجاد یک تابع افزونه دیگر در NotificationUtils.kt خود شروع کنید. NotificationManager یک API برای لغو تمام اعلان‌های فعال به نام cancelAll () دارد.

  1. NotificationsUtil.kt را باز کنید.
  2. یک تابع افزونه در NotificationManager اضافه کنید که cancelAll() را فراخوانی می کند.
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. EggTimerViewModel.kt را باز کرده و به تابع startTimer() بروید.
  2. در داخل startTimer() یک نمونه از NotificationManager را از سیستم دریافت کنید و cancelNotifications() را فراخوانی کنید.
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. برنامه را اجرا کنید و تایمر را شروع کنید.
  2. پس از مشاهده اعلان، تایمر را دوباره راه اندازی کنید و مشاهده کنید که چگونه برنامه ما به طور خودکار اعلان قبلی را از نوار وضعیت حذف می کند.

چارچوب اعلان‌ها گزینه‌های سفارشی‌سازی متنوعی را در اختیار توسعه‌دهندگان قرار می‌دهد تا اقدامات سفارشی را تنظیم کرده و اعلان‌های خود را در صورت لزوم سبک‌دهی کنند. در طول این کار، یاد خواهید گرفت که چگونه اعلان های تایمر تخم مرغ خود را سفارشی کنید.

مرحله 1: اعلان خود را سبک کنید

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

NotificationCompat سبک های داخلی را برای موارد زیر ارائه می دهد:

  • BigTextStyle ، که می تواند بلوک بزرگی از متن را نمایش دهد، مانند نمایش محتوای یک ایمیل در صورت باز شدن.
  • BigPictureStyle ، که اعلان‌های با فرمت بزرگ را نشان می‌دهد که شامل یک پیوست تصویر بزرگ است.
  • InboxStyle ، که محتوای متنی سبک مکالمه را نشان می دهد.
  • MediaStyle ، که کنترل‌هایی را برای پخش رسانه نشان می‌دهد.
  • MessagingStyle ، که اعلان‌های با فرمت بزرگ را نشان می‌دهد که شامل پیام‌های متعدد بین هر تعداد نفر می‌شود.

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

  1. NotificationUtils.kt را باز کرده و تابع sendNotification() را پیدا کنید.
  2. با بارگیری یک تصویر از resources با استفاده از BitmapFactory کنید.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. یک BigPictureStyle جدید ایجاد کنید و تصویر خود را تنظیم کنید.
  2. bigLargeIcon() را روی null قرار دهید تا وقتی اعلان بزرگ شد، نماد بزرگ از بین برود.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
        .bigPicture(eggImage)
        .bigLargeIcon(null)
  1. استایل را با setStyle() روی bigPicStyle کنید.
  2. نماد بزرگ با setLargeIcon() را روی eggImage قرار دهید، بنابراین وقتی اعلان جمع می شود، تصویر به عنوان یک نماد کوچکتر نمایش داده می شود.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
  1. برنامه را اجرا کنید و یک تایمر تنظیم کنید. هنگامی که اعلان برای اولین بار نشان داده می شود، در کشوی اعلان در حالت جمع شده است. اگر اعلان را گسترش دهید، یک تصویر بزرگ در ناحیه اعلان توسعه یافته نشان داده می شود.

مرحله 2: اقدامات اطلاع رسانی

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

یک اعلان می تواند حداکثر سه دکمه عمل ارائه دهد که به کاربر امکان می دهد سریع پاسخ دهد، مانند به تعویق انداختن یادآوری یا پاسخ به یک پیام متنی. این دکمه‌های عمل نباید عملکردی را که هنگام ضربه زدن کاربر روی اعلان انجام می‌شود، تکرار کنند.

برای افزودن یک دکمه اقدام، یک PendingIntent را به addAction() ارسال کنید. عملکرد بر روی سازنده این شبیه به تنظیم عملکرد ضربه زدن پیش‌فرض اعلان با فراخوانی setContentIntent() است، به جز اینکه به جای راه‌اندازی یک اکتیویتی، می‌توانید کارهای مختلف دیگری را انجام دهید، برای مثال، یک BroadcastReceiver را راه‌اندازی کنید که یک کار را در پس‌زمینه انجام می‌دهد تا عمل انجام شود. برنامه ای که از قبل باز است را قطع نکنید.

در این کد لبه، قبلاً یک BoadcastReceiver به نام SnoozeReceiver به شما داده شده است. شما از SnoozeReceiver برای دریافت کلیک کاربر روی اکشن Notification استفاده خواهید کرد. در مراحل زیر کدی را اضافه می‌کنید تا زمانی که کاربر دکمه عمل به تعویق را می‌زند، اعلان تایمر تخم مرغ را به مدت 60 ثانیه به تعویق بیندازید. هنگامی که روی عملکرد تعویق کلیک می شود، SnoozeReceiver یک هدف دریافت می کند و یک زنگ جدید برای ارسال یک اعلان جدید پس از 60 ثانیه ایجاد می کند.

  1. SnoozeReceiver.kt باز کنید. این کلاس مشابه AlarmReceiver است که قبلاً استفاده می کردید. در مراحل زیر کدی را اضافه می کنید که onReceive() SnoozeReceiver را فعال می کند. به طور خلاصه، کد موجود در SnoozeReceiver یک زنگ هشدار جدید برای ارسال یک اعلان جدید یک دقیقه بعد ایجاد می کند. به پایین تابع onReceive بروید، یک نمونه از notificationManager را از سیستم دریافت کنید و cancelAll را فراخوانی کنید.
// SnoozeReceiver.kt
        val notificationManager = ContextCompat.getSystemService(
            context,
            NotificationManager::class.java
        ) as NotificationManager
        notificationManager.cancelAll()
  1. برای استفاده از SnoozeReceiver ، NotificationUtils.kt را باز کنید.
  2. یک Intent snoozeIntent جدید برای SnoozeReceiver درست بعد از استایل در تابع sendNotification() ایجاد کنید.
  3. با فراخوانی getBroadcast() در PendingIntent که انتظار پارامترهای مراحل زیر را دارد، یک intent در انتظار ایجاد کنید. این PendingIntent توسط سیستم برای تنظیم زنگ هشدار جدید برای ارسال یک اعلان جدید پس از 60 ثانیه زمانی که کاربر روی دکمه تعویق ضربه می زند، استفاده می کند.
  4. اولین پارامتر زمینه برنامه است که این PendingIntent باید فعالیت را در آن شروع کند.
  5. پارامتر دوم کد درخواست است که کد درخواستی برای این هدف معلق است. اگر نیاز به به‌روزرسانی یا لغو این هدف معلق دارید، باید از این کد برای دسترسی به هدف معلق استفاده کنید.
  6. سپس، شی snoozeIntent را اضافه کنید، که هدف فعالیتی است که باید راه اندازی شود.
  7. در نهایت، مقدار پرچم #FLAG_ONE_SHOT را اضافه کنید، زیرا هدف فقط یک بار استفاده خواهد شد. اقدام سریع و اعلان پس از اولین ضربه ناپدید می شوند، به همین دلیل است که قصد فقط یک بار قابل استفاده است.
// NotificationUtils.kt

// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
    applicationContext, 
    REQUEST_CODE, 
    snoozeIntent, 
    FLAGS
)
  1. سپس تابع addAction() را در notificationBuilder فراخوانی کنید. این تابع انتظار دارد که یک نماد و یک متن عملکرد شما را برای کاربر توصیف کند. همچنین باید snoozeIntent را اضافه کنید. این هدف برای فعال کردن boadcastReceiver مناسب زمانی که روی عملکرد شما کلیک می‌شود استفاده می‌شود.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
    R.drawable.egg_icon, 
    applicationContext.getString(R.string.snooze),
    snoozePendingIntent
)
  1. برنامه تایمر تخم مرغ را اجرا کنید تا عمل چرت زدن را آزمایش کنید.
  2. تایمر را اجرا کنید و برنامه را در پس زمینه قرار دهید. پس از اتمام تایمر، اعلان را گسترش دهید و خواهید دید که اعلان اکنون دارای یک دکمه عمل به تعویق است که تایمر تخم مرغ را برای یک دقیقه دیگر به تعویق می‌اندازد.

مرحله 3: اهمیت اعلان

اهمیت تعیین می‌کند که نوتیفیکیشن تا چه اندازه باید کاربر را از نظر بصری و شنیداری قطع کند. اعلان‌های با اهمیت بالاتر برای کاربران مزاحم‌تر خواهند بود.

شما باید سطح اهمیت را در سازنده NotificationChannel مشخص کنید. شما در ابتدا اهمیت کمی را برای برنامه تایمر تخم مرغ تعیین کردید. می‌توانید از یکی از پنج سطح اهمیت، از IMPORTANCE_NONE(0) تا IMPORTANCE_HIGH(4) استفاده کنید. سطح اهمیتی که به یک کانال اختصاص می‌دهید برای همه پیام‌های اعلانی که به آن کانال ارسال می‌کنید اعمال می‌شود.

سطوح اهمیت کانال

سطح اهمیت قابل مشاهده توسط کاربر

اهمیت (اندروید 8.0 و بالاتر)

اولویت (اندروید 7.1 و پایین تر)

صدا می دهد و به عنوان یک اعلان هدآپ ظاهر می شود (در بالای صفحه ظاهر می شود)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

صدا می دهد

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

بدون صدا

IMPORTANCE_LOW

PRIORITY_LOW

بدون صدا و در نوار وضعیت ظاهر نمی شود

IMPORTANCE_MIN

PRIORITY_MIN

برای کسب اطلاعات در مورد انتخاب یک سطح اولویت مناسب، به "سطوح اولویت" در راهنمای طراحی اعلان ها مراجعه کنید. هنگام انتخاب سطح اهمیت برای اعلان‌ها در برنامه خود باید مراقب باشید. اهمیت کانال باید با در نظر گرفتن زمان و توجه کاربر انتخاب شود. هنگامی که یک اعلان بی اهمیت به عنوان اضطراری پنهان می شود، می تواند زنگ هشدار غیرضروری ایجاد کند و حواس پرت شود. کاربران کنترل کاملی بر سطح اهمیت اعلان های خود دارند، بنابراین اگر یک اعلان آزاردهنده ایجاد کنید، می توانند کانال اعلان شما را به طور کامل خاموش کنند.

هنگامی که برای اولین بار اعلان را در مرحله 1.6 ایجاد کردید، تایمر تخم مرغ برای ارسال اعلان‌ها با اولویت پایین تنظیم شده بود، زیرا برای ایجاد مزاحمت برای کاربر با اعلان‌ها طراحی شده بود. با این حال، ممکن است ایده خوبی باشد که توجه کاربر را قبل از پختن بیش از حد تخم مرغ جلب کنید. برای تغییر سطح اهمیت اعلان، از تنظیمات کانال شروع کنید. اهمیت کانال بر سطح وقفه همه اعلان های ارسال شده در کانال تأثیر می گذارد و باید در سازنده NotificationChannel مشخص شود.

  1. برای تغییر سطح اهمیت کانال اعلان برنامه خود، EggTimerFragment.kt را باز کنید و به createChannel() بروید. سطح اهمیت را از IMPORTANCE_LOW به IMPORTANCE_HIGH تغییر دهید.
// EggTimerFragment.kt
    val notificationChannel = NotificationChannel(
        channelId,
        channelName,
        // TODO: Step 2.4 change importance
        NotificationManager.IMPORTANCE_HIGH
    )

برای پشتیبانی از دستگاه‌های دارای Android 7.1 (سطح API 25) یا پایین‌تر، باید برای هر اعلان با استفاده از یک ثابت اولویت از کلاس NotificationCompat ، setPriority() را نیز فراخوانی کنید.

  1. NotificationUtils.kt را باز کنید و موارد زیر را به شیء سازنده اعلان اضافه کنید.
// NotificationUtils.kt
   .addAction(
       R.drawable.common_google_signin_btn_icon_dark,
       applicationContext.getString(R.string.snooze),
       snoozePendingIntent
    )
   // TODO: Step 2.5 set priority
    .setPriority(NotificationCompat.PRIORITY_HIGH)
  1. قبل از اجرای برنامه، روی نماد برنامه در دستگاه یا شبیه ساز خود برای مدت طولانی کلیک کنید و حذف نصب را انتخاب کنید تا تنظیمات کانال قبلی پاک شود. اگر نتوانید برنامه را حذف نصب کنید، تنظیمات اولویت کانال تغییر نمی کند و این باعث می شود که هنگام ارسال اعلان تغییری در رفتار ایجاد نشود.
  2. حالا دوباره برنامه را اجرا کنید و تایمر را شروع کنید. این بار، هنگامی که اعلان تحویل داده می شود، بدون توجه به اینکه برنامه شما در پیش زمینه یا پس زمینه اجرا می شود، باید یک پنجره بازشو در بالای صفحه ظاهر شود.

مرحله 4: نشان های اعلان

نشان‌های اعلان نقطه‌های کوچکی هستند که وقتی برنامه یک اعلان فعال دارد، روی نماد راه‌انداز برنامه مرتبط ظاهر می‌شوند. کاربران می توانند برای نمایش اعلان ها، روی نماد برنامه به مدت طولانی فشار دهند.

این نقاط که نشان نامیده می شوند به طور پیش فرض ظاهر می شوند و برنامه شما نیازی به انجام کاری ندارد. با این حال، ممکن است موقعیت‌هایی وجود داشته باشد که نشان‌ها برای اعلان‌های شما معنی نداشته باشند، بنابراین می‌توانید با فراخوانی setShowBadge(false) در شی NotificationChannel ، آنها را بر اساس هر کانال غیرفعال کنید. از آنجایی که تایمر تخم مرغ در یک زمان معین فقط یک اعلان فعال دارد، نشان روی نماد برنامه شما فایده چندانی برای کاربران شما ندارد. در مراحل زیر نشان را غیرفعال می‌کنید و فقط یک اعلان برای تایمر تخم مرغ نشان می‌دهید.

  1. setShowBadge(false) را به کد ایجاد کانال برای تایمر تخم مرغ اضافه کنید تا نشان ها را غیرفعال کنید.
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. برنامه را دوباره اجرا کنید، تایمر را روشن کنید و نماد برنامه را تماشا کنید. شما نباید هیچ نشانی را روی نماد برنامه ببینید.

کد راه حل در شاخه اصلی کد دانلود شده شما قرار دارد.

  • از کلاس NotificationManager برای ایجاد، ارسال، به روز رسانی و لغو اعلان استفاده کنید.
  • از یک شی NotificationChannel با متد createNotificationChannel برای تنظیم یک کانال برای اعلان استفاده کنید.
  • از addAction() برای افزودن اقدامات سریع به اعلان استفاده کنید.
  • از setShowBadge() برای فعال یا غیرفعال کردن نشان ها استفاده کنید.
  • اعلان‌های خود را با استفاده از سبک‌هایی که از Notification.Style گسترش می‌یابد، سبک دهید
  • سطح اهمیت را با NotificationChannel.setImportance () تنظیم کنید

دوره بی ادبی:

مستندات توسعه دهنده اندروید:

برای پیوند به دیگر کدلب ها در این دوره، صفحه فرود Advanced Android in Kotlin Codelabs را ببینید.