یک اعلان ایجاد کنید

اعلان‌ها اطلاعات کوتاه و به‌موقعی در مورد رویدادهای برنامه شما در زمانی که از آن استفاده نمی‌شود، ارائه می‌دهند. این سند به شما نشان می‌دهد که چگونه یک اعلان با ویژگی‌های مختلف ایجاد کنید. برای آشنایی با نحوه نمایش اعلان‌ها در اندروید، به نمای کلی اعلان‌ها مراجعه کنید. برای نمونه کدی که از اعلان‌ها استفاده می‌کند، به نمونه SociaLite در GitHub مراجعه کنید.

کد موجود در این صفحه از APIهای NotificationCompat از کتابخانه AndroidX استفاده می‌کند. این APIها به شما امکان می‌دهند ویژگی‌هایی را که فقط در نسخه‌های جدیدتر اندروید موجود هستند، اضافه کنید و در عین حال سازگاری با اندروید ۹ (سطح API 28) را نیز حفظ کنید. با این حال، برخی از ویژگی‌ها، مانند عملکرد پاسخ درون‌خطی، منجر به عدم انجام عملیات در نسخه‌های قبلی می‌شوند.

ایجاد یک اعلان پایه

یک اعلان در ابتدایی‌ترین و فشرده‌ترین شکل خود - که به عنوان فرم جمع‌شده نیز شناخته می‌شود - یک آیکون، یک عنوان و مقدار کمی محتوای متنی را نمایش می‌دهد. این بخش نحوه ایجاد اعلانی را نشان می‌دهد که کاربر می‌تواند برای راه‌اندازی یک فعالیت در برنامه شما روی آن ضربه بزند.

شکل ۱. یک اعلان با یک آیکون، یک عنوان و مقداری متن.

برای جزئیات بیشتر در مورد هر بخش از یک اعلان، بخش «آناتومی اعلان» را مطالعه کنید.

اعلام مجوز زمان اجرا

اندروید ۱۳ (سطح API ۳۳) و بالاتر از یک مجوز زمان اجرا برای ارسال اعلان‌های غیرمعاف (از جمله سرویس‌های پیش‌زمینه (FGS)) از یک برنامه پشتیبانی می‌کند.

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

<manifest ...>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application ...>
        ...
    </application>
</manifest>

برای جزئیات بیشتر در مورد مجوزهای زمان اجرا، به مجوز زمان اجرای اعلان مراجعه کنید.

تنظیم محتوای اعلان

برای شروع، محتوا و کانال اعلان را با استفاده از شیء NotificationCompat.Builder تنظیم کنید. مثال زیر نحوه ایجاد یک اعلان با موارد زیر را نشان می‌دهد:

  • یک آیکون کوچک، که توسط setSmallIcon() تنظیم شده است. این تنها محتوای قابل مشاهده توسط کاربر است که مورد نیاز است.

  • یک عنوان، که توسط setContentTitle() تنظیم می‌شود.

  • متن بدنه، که توسط setContentText() تنظیم شده است.

  • اولویت اعلان، که توسط setPriority() تنظیم می‌شود. اولویت، میزان مزاحمت اعلان را در اندروید ۷.۱ و قبل از آن تعیین می‌کند. برای اندروید ۸.۰ و بعد از آن، به جای آن، اهمیت کانال را همانطور که در بخش بعدی نشان داده شده است، تنظیم کنید.

کاتلین

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

جاوا

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

سازنده‌ی NotificationCompat.Builder از شما می‌خواهد که یک شناسه‌ی کانال ارائه دهید. این شناسه برای سازگاری با اندروید ۸.۰ (سطح API ۲۶) و بالاتر لازم است، اما توسط نسخه‌های قبلی نادیده گرفته می‌شود.

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

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

اگر می‌خواهید اعلان شما طولانی‌تر باشد، می‌توانید با اضافه کردن یک قالب سبک با setStyle() یک اعلان قابل گسترش را فعال کنید. برای مثال، کد زیر یک ناحیه متنی بزرگتر ایجاد می‌کند:

کاتلین

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        <b>.setStyle(NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))</b>
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)

جاوا

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Much longer text that cannot fit one line...")
        <b>.setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))</b>
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

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

یک کانال ایجاد کنید و اهمیت آن را تعیین کنید

قبل از اینکه بتوانید اعلان را در اندروید ۸.۰ و بالاتر ارسال کنید، کانال اعلان برنامه خود را با ارسال نمونه‌ای از NotificationChannel به createNotificationChannel() در سیستم ثبت کنید. کد زیر توسط یک شرط در نسخه SDK_INT مسدود شده است:

کاتلین

private fun createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val name = getString(R.string.channel_name)
        val descriptionText = getString(R.string.channel_description)
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
            description = descriptionText
        }
        // Register the channel with the system.
        val notificationManager: NotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}

جاوا

private void createNotificationChannel() {
    // Create the NotificationChannel, but only on API 26+ because
    // the NotificationChannel class is not in the Support Library.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system; you can't change the importance
        // or other notification behaviors after this.
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

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

سازنده‌ی NotificationChannel به یک importance نیاز دارد که از یکی از ثابت‌های کلاس NotificationManager استفاده می‌کند. این پارامتر نحوه‌ی قطع کردن اعلان‌های متعلق به این کانال را برای کاربر تعیین می‌کند. اولویت را با setPriority() تنظیم کنید تا از اندروید ۷.۱ و قبل از آن پشتیبانی کند، همانطور که در مثال قبل نشان داده شده است.

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

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

تنظیم عملکرد ضربه زدن به اعلان

هر اعلان باید به یک لمس پاسخ دهد، معمولاً برای باز کردن یک activity در برنامه شما که مربوط به اعلان است. برای انجام این کار، یک content intent تعریف شده با یک شیء PendingIntent را مشخص کنید و آن را به setContentIntent() منتقل کنید.

قطعه کد زیر نحوه ایجاد یک اینتنت ساده برای باز کردن یک اکتیویتی هنگام لمس اعلان توسط کاربر را نشان می‌دهد:

کاتلین

// Create an explicit intent for an Activity in your app.
<b>val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}</b>
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        <b>.setContentIntent(pendingIntent)</b>
        .setAutoCancel(true)

جاوا

// Create an explicit intent for an Activity in your app.
<b>Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);</b>
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        // Set the intent that fires when the user taps the notification.
        <b>.setContentIntent(pendingIntent)</b>
        .setAutoCancel(true);

این کد تابع setAutoCancel() فراخوانی می‌کند که به طور خودکار اعلان را هنگام ضربه زدن کاربر حذف می‌کند .

پرچم‌های intent در مثال قبلی، تجربه ناوبری مورد انتظار کاربر را پس از باز شدن برنامه شما با استفاده از اعلان، حفظ می‌کنند. بسته به نوع فعالیتی که شروع می‌کنید، می‌توانید از آن استفاده کنید، که می‌تواند یکی از موارد زیر باشد:

  • یک فعالیت (Activity) که منحصراً برای پاسخ به اعلان وجود دارد. هیچ دلیلی وجود ندارد که کاربر در طول استفاده عادی از برنامه به این فعالیت هدایت شود، بنابراین این فعالیت به جای اضافه شدن به وظیفه موجود برنامه و back Stack ، یک وظیفه جدید را آغاز می‌کند. این نوع intent در نمونه قبلی ایجاد شده است.

  • یک اکتیویتی که در جریان عادی برنامه شما وجود دارد. در این حالت، شروع اکتیویتی یک پشته پشتی ایجاد می‌کند تا انتظارات کاربر برای دکمه‌های Back و Up حفظ شود.

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

نمایش اعلان

برای نمایش اعلان، تابع NotificationManagerCompat.notify() را فراخوانی کنید و یک شناسه منحصر به فرد برای اعلان و نتیجه‌ی تابع NotificationCompat.Builder.build() به آن ارسال کنید. این موضوع در مثال زیر نشان داده شده است:

کاتلین

with(NotificationManagerCompat.from(this)) {
    if (ActivityCompat.checkSelfPermission(
            this@MainActivity,
            Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        // ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        // public fun onRequestPermissionsResult(requestCode: Int, permissions: Array&lt;out String&gt;,
        //                                        grantResults: IntArray)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        return@with
    }
    // notificationId is a unique int for each notification that you must define.
    notify(NOTIFICATION_ID, builder.build())
}

جاوا

if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
    // TODO: Consider calling
    // ActivityCompat#requestPermissions
    // here to request the missing permissions, and then overriding
    // public void onRequestPermissionsResult(int requestCode, String[] permissions,
    //                                        int[] grantResults)
    // to handle the case where the user grants the permission. See the documentation
    // for ActivityCompat#requestPermissions for more details.
    return;
}
NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, builder.build());

شناسه اعلانی که به NotificationManagerCompat.notify() ارسال می‌کنید را ذخیره کنید، زیرا وقتی می‌خواهید اعلان را به‌روزرسانی یا حذف کنید، به آن نیاز دارید.

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

دکمه‌های عملیاتی اضافه کنید

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

شکل ۳. یک اعلان با یک دکمه‌ی عملیاتی.

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

برای مثال، کد زیر نحوه ارسال یک broadcast به یک گیرنده خاص را نشان می‌دهد:

کاتلین

val ACTION_SNOOZE = "snooze"

<b>val snoozeIntent = Intent(this, MyBroadcastReceiver::class.java).apply {
    action = ACTION_SNOOZE
    putExtra(EXTRA_NOTIFICATION_ID, 0)
}
val snoozePendingIntent: PendingIntent =
    PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)</b>
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        <b>.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)</b>

جاوا

String ACTION_SNOOZE = "snooze"

<b>Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);</b>

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        <b>.addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);</b>

برای اطلاعات بیشتر در مورد ساخت یک BroadcastReceiver برای اجرای کارهای پس‌زمینه، به نمای کلی Broadcasts مراجعه کنید.

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

افزودن قابلیت پاسخ مستقیم

قابلیت پاسخ مستقیم (direct reply) که در اندروید ۷.۰ (API level 24) معرفی شد، به کاربران اجازه می‌دهد متن را مستقیماً در اعلان وارد کنند. سپس متن بدون باز کردن هیچ فعالیتی به برنامه شما ارسال می‌شود. به عنوان مثال، می‌توانید از یک قابلیت پاسخ مستقیم استفاده کنید تا به کاربران اجازه دهید به پیام‌های متنی پاسخ دهند یا لیست کارها را از داخل اعلان به‌روزرسانی کنند.

شکل ۴. ضربه زدن روی دکمه «پاسخ» ورودی متن را باز می‌کند.

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

دکمه پاسخ را اضافه کنید

برای ایجاد یک اکشن اعلان که از پاسخ مستقیم پشتیبانی می‌کند، این مراحل را دنبال کنید:

  1. یک نمونه از RemoteInput.Builder ایجاد کنید که بتوانید آن را به اکشن اعلان خود اضافه کنید. سازنده‌ی این کلاس، رشته‌ای را که سیستم به عنوان کلید ورودی متن استفاده می‌کند، می‌پذیرد. برنامه‌ی شما بعداً از آن کلید برای بازیابی متن ورودی استفاده می‌کند. * {Kotlin} ```kotlin // کلید برای رشته‌ای که در intent اکشن تحویل داده می‌شود. private val KEY_TEXT_REPLY = "key_text_reply" var replyLabel: String = resources.getString(R.string.reply_label) var remoteInput: RemoteInput = RemoteInput.Builder(KEY_TEXT_REPLY).run { setLabel(replyLabel) build() } ``` * {Java} ```java // کلید برای رشته‌ای که در intent اکشن تحویل داده می‌شود. private static final String KEY_TEXT_REPLY = "key_text_reply"; رشته replyLabel = getResources().getString(R.string.reply_label); ورودی از راه دور remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build(); ````
  2. یک PendingIntent برای اکشن پاسخ ایجاد کنید. * {Kotlin} ```kotlin // یک PendingIntent برای فعال شدن اکشن پاسخ بسازید. var replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(applicationContext, conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT) ``` * {Java} ```java // یک PendingIntent برای فعال شدن اکشن پاسخ بسازید. PendingIntent replyPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT); ````
  3. شیء RemoteInput را با استفاده از addRemoteInput() به یک اکشن متصل کنید. * {Kotlin} ```kotlin // اکشن پاسخ را ایجاد کنید و ورودی ریموت را اضافه کنید. var action: NotificationCompat.Action = NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build() ``` * {Java} ```java // اکشن پاسخ را ایجاد کنید و ورودی ریموت را اضافه کنید. NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .build(); ````
  4. اعمال اکشن به یک اعلان و انتشار اعلان. * {Kotlin} ```kotlin // اعلان را بسازید و اکشن را اضافه کنید. val newMessageNotification = Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build() // صدور اعلان. with(NotificationManagerCompat.from(this)) { notificationManager.notify(notificationId, newMessageNotification) } ``` * {Java} ```java // اعلان را بسازید و اکشن را اضافه کنید. اعلان newMessageNotification = new Notification.Builder(context, CHANNEL_ID) .setSmallIcon(R.drawable.ic_message) .setContentTitle(getString(R.string.title)) .setContentText(getString(R.string.content)) .addAction(action) .build(); // صدور اعلان. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, newMessageNotification); ````

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

بازیابی ورودی کاربر از پاسخ

برای دریافت ورودی کاربر از رابط کاربری پاسخ اعلان، RemoteInput.getResultsFromIntent() را فراخوانی کنید و Intent دریافتی توسط BroadcastReceiver خود را به آن ارسال کنید:

کاتلین

private fun getMessageText(intent: Intent): CharSequence? {
    return RemoteInput.getResultsFromIntent(intent)?.getCharSequence(KEY_TEXT_REPLY)
}

جاوا

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

پس از پردازش متن، با فراخوانی NotificationManagerCompat.notify() با همان شناسه و برچسب، در صورت استفاده، اعلان را به‌روزرسانی کنید. این کار برای پنهان کردن رابط کاربری پاسخ مستقیم و تأیید به کاربر مبنی بر دریافت و پردازش صحیح پاسخ، ضروری است.

کاتلین

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
val repliedNotification = Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build()

// Issue the new notification.
NotificationManagerCompat.from(this).apply {
    notificationManager.notify(notificationId, repliedNotification)
}

جاوا

// Build a new notification, which informs the user that the system
// handled their interaction with the previous notification.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

// Issue the new notification.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

بازیابی داده‌های دیگر

مدیریت سایر انواع داده با RemoteInput به طور مشابه کار می‌کند. مثال زیر از تصویر به عنوان ورودی استفاده می‌کند.

کاتلین

  // Key for the data that's delivered in the action's intent.
  private val KEY_REPLY = "key_reply"
  var replyLabel: String = resources.getString(R.string.reply_label)
  var remoteInput: RemoteInput = RemoteInput.Builder(KEY_REPLY).run {
      setLabel(replyLabel)
      // Allow for image data types in the input
  // This method can be used again to
  // allow for other data types
      setAllowDataType("image/*", true)
      build()
}

تابع RemoteInput#getDataResultsFromIntent فراخوانی کنید و داده‌های مربوطه را استخراج کنید.

کاتلین

  import android.app.RemoteInput;
  import android.content.Intent;
  import android.os.Bundle;

  class ReplyReceiver: BroadcastReceiver()  {

      public static final String KEY_DATA = "key_data";

      public static void handleRemoteInput(Intent intent) {
          Bundle dataResults = RemoteInput.getDataResultsFromIntent(intent, KEY_DATA);
          val imageUri: Uri? = dataResults.values.firstOrNull()
          if (imageUri != null) {
              // Extract the image
          try {
                  val inputStream = context.contentResolver.openInputStream(imageUri)
                  val bitmap = BitmapFactory.decodeStream(inputStream)
                  // Display the image
                  // ...
              } catch (e: Exception) {
                  Log.e("ReplyReceiver", "Failed to process image URI", e)
              }
      }
  }

هنگام کار با این اعلان جدید، از زمینه‌ای که به متد onReceive() گیرنده ارسال شده است، استفاده کنید.

با فراخوانی setRemoteInputHistory() پاسخ را به پایین اعلان اضافه کنید. با این حال، اگر در حال ساخت یک برنامه پیام‌رسان هستید، یک اعلان به سبک پیام‌رسان ایجاد کنید و پیام جدید را به مکالمه اضافه کنید.

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

نمایش پیام فوری

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

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

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

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

کاتلین

val fullScreenIntent = Intent(this, ImportantActivity::class.java)
val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        <b>.setFullScreenIntent(fullScreenPendingIntent, true)</b>

جاوا

Intent fullScreenIntent = new Intent(this, ImportantActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        <b>.setFullScreenIntent(fullScreenPendingIntent, true);</b>

تنظیم میزان دید صفحه قفل

برای کنترل سطح جزئیات قابل مشاهده در اعلان از صفحه قفل، تابع setVisibility() را فراخوانی کرده و یکی از مقادیر زیر را مشخص کنید:

  • VISIBILITY_PUBLIC : محتوای کامل اعلان در صفحه قفل نمایش داده می‌شود.

  • VISIBILITY_SECRET : هیچ بخشی از اعلان در صفحه قفل نشان داده نمی‌شود.

  • VISIBILITY_PRIVATE : فقط اطلاعات اولیه، مانند آیکون اعلان و عنوان محتوا، روی صفحه قفل نشان داده می‌شود. محتوای کامل اعلان نمایش داده نمی‌شود.

وقتی VISIBILITY_PRIVATE را تنظیم می‌کنید، می‌توانید یک نسخه جایگزین از محتوای اعلان ارائه دهید که جزئیات خاصی را پنهان می‌کند. برای مثال، یک برنامه پیامکی ممکن است اعلانی را نمایش دهد که نشان می‌دهد "شما 3 پیام متنی جدید دارید" اما محتوای پیام و فرستنده‌ها را پنهان می‌کند. برای ارائه این اعلان جایگزین، ابتدا اعلان جایگزین را با NotificationCompat.Builder طبق معمول ایجاد کنید. سپس، اعلان جایگزین را با setPublicVersion() به اعلان معمولی پیوست کنید.

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

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

برای به‌روزرسانی یک اعلان پس از صدور آن، دوباره تابع NotificationManagerCompat.notify() را فراخوانی کنید و همان شناسه‌ای را که قبلاً استفاده کرده‌اید به آن ارسال کنید. اگر اعلان قبلی رد شود، یک اعلان جدید به جای آن ایجاد می‌شود.

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

حذف یک اعلان

اعلان‌ها تا زمانی که یکی از موارد زیر اتفاق بیفتد، قابل مشاهده باقی می‌مانند:

  • کاربر اعلان را رد می‌کند.
  • اگر هنگام ایجاد اعلان، تابع setAutoCancel() را فراخوانی کنید، کاربر اعلان را لمس می‌کند.
  • شما تابع cancel() برای یک شناسه اعلان خاص فراخوانی می‌کنید. این متد همچنین اعلان‌های جاری را حذف می‌کند.
  • شما cancelAll() را فراخوانی می‌کنید که تمام اعلان‌هایی را که قبلاً صادر کرده‌اید حذف می‌کند.
  • اگر هنگام ایجاد اعلان، با استفاده از setTimeoutAfter() یک مهلت زمانی تعیین کنید، مدت زمان مشخص شده سپری می‌شود. در صورت لزوم، می‌توانید قبل از پایان مدت زمان مشخص شده، اعلان را لغو کنید.

بهترین شیوه‌ها برای برنامه‌های پیام‌رسان

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

از MessagingStyle استفاده کنید

از اندروید ۷.۰ (API سطح ۲۴)، اندروید یک الگوی سبک اعلان (notification style) مخصوص محتوای پیام‌رسانی ارائه می‌دهد. با استفاده از کلاس NotificationCompat.MessagingStyle ، می‌توانید چندین برچسب نمایش داده شده در اعلان، از جمله عنوان مکالمه، پیام‌های اضافی و نمای محتوا برای اعلان را تغییر دهید.

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

کاتلین

val user = Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build()

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with $sender")
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build()

جاوا

Person user = new Person.Builder()
    .setIcon(userIcon)
    .setName(userName)
    .build();

Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setContentTitle("2 new messages with " + sender)
    .setContentText(subject)
    .setSmallIcon(R.drawable.new_message)
    .setStyle(new NotificationCompat.MessagingStyle(user)
        .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
        .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
    )
    .build();

از اندروید ۹.۰ (سطح API 28)، برای رندر بهینه اعلان و آواتارهای آن، استفاده از کلاس Person نیز الزامی است.

هنگام استفاده از NotificationCompat.MessagingStyle ، موارد زیر را انجام دهید:

  • برای تنظیم عنوان برای چت‌های گروهی با بیش از دو نفر، تابع MessagingStyle.setConversationTitle() را فراخوانی کنید. یک عنوان خوب برای مکالمه می‌تواند نام چت گروهی یا اگر نامی ندارد، فهرستی از شرکت‌کنندگان در مکالمه باشد. بدون این، ممکن است پیام به عنوان یک مکالمه‌ی یک به یک با فرستنده‌ی جدیدترین پیام در مکالمه اشتباه گرفته شود.
  • از متد MessagingStyle.setData() برای درج پیام‌های رسانه‌ای مانند تصاویر استفاده کنید. انواع MIME الگوی image/* پشتیبانی می‌شوند.

از پاسخ مستقیم استفاده کنید

پاسخ مستقیم به کاربر اجازه می‌دهد تا به صورت درون‌خطی به یک پیام پاسخ دهد.

  • پس از اینکه کاربر با اکشن پاسخ درون‌خطی پاسخ داد، از MessagingStyle.addMessage() برای به‌روزرسانی اعلان MessagingStyle استفاده کنید و اعلان را پس نگیرید یا لغو نکنید. لغو نکردن اعلان به کاربر اجازه می‌دهد تا چندین پاسخ از اعلان ارسال کند.
  • برای اینکه اکشن پاسخ درون‌خطی با Wear OS سازگار باشد، Action.WearableExtender.setHintDisplayInlineAction(true) را فراخوانی کنید.
  • با اضافه کردن پیام‌های تاریخی به اعلان، از متد addHistoricMessage() برای ارائه زمینه به یک مکالمه پاسخ مستقیم استفاده کنید.

فعال کردن پاسخ هوشمند

  • برای فعال کردن پاسخ هوشمند، تابع setAllowGeneratedResponses(true) را در اکشن پاسخ فراخوانی کنید. این باعث می‌شود پاسخ‌های پاسخ هوشمند هنگام اتصال اعلان به دستگاه Wear OS برای کاربران در دسترس باشند. پاسخ‌های پاسخ هوشمند توسط یک مدل یادگیری ماشین کاملاً on-watch با استفاده از زمینه ارائه شده توسط اعلان NotificationCompat.MessagingStyle تولید می‌شوند و هیچ داده‌ای برای تولید پاسخ‌ها در اینترنت آپلود نمی‌شود.

اضافه کردن فراداده اعلان

  • فراداده‌های اعلان را به سیستم اختصاص دهید تا به سیستم بگویید چگونه اعلان‌های برنامه شما را هنگامی که دستگاه در Do Not Disturb mode است، مدیریت کند. برای مثال، از متد addPerson() یا setCategory(Notification.CATEGORY_MESSAGE) برای لغو حالت «مزاحم نشوید» استفاده کنید.