إنشاء إشعار

توفّر الإشعارات معلومات قصيرة وفي الوقت المناسب حول الأحداث داخل تطبيقك أثناء فليس قيد الاستخدام. يوضّح لك هذا المستند كيفية إنشاء إشعار يحتوي على ميزات مختلفة. للاطّلاع على مقدمة حول كيفية ظهور الإشعارات على أجهزة Android، راجِع نظرة عامة على الإشعارات. للحصول على نموذج للرمز البرمجي الذي يستخدم الإشعارات، اطّلِع على نموذج ملف "الأشخاص" على GitHub.

تستخدم التعليمة البرمجية في هذه الصفحة NotificationCompat واجهات برمجة التطبيقات من مكتبة AndroidX. تتيح لك واجهات برمجة التطبيقات هذه إضافة ميزات متوفّرة فقط على الإصدارات الأحدث من Android مع الحفاظ على التوافق مع الإصدار 9 من Android (المستوى 28 لواجهة برمجة التطبيقات). ومع ذلك، هناك بعض الميزات، مثل إجراء الرد المضمّن، إلى عدم وجود عملية على الإصدارات السابقة.

إضافة مكتبة AndroidX Core

وعلى الرغم من أن معظم المشاريع التي تم إنشاؤها باستخدام "استوديو Android" تتضمن المختلفة لاستخدام NotificationCompat، تحقق من أن المستوى يتضمن ملف build.gradle التبعية التالية:

رائع

dependencies {
    implementation "androidx.core:core:2.2.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-ktx:2.2.0")
}

إنشاء إشعار أساسي

يظهر الإشعار في أبسط شكله الأساسي ومكثفه، ويُعرف أيضًا باسم الإشعار المصغَّر. form — يعرض رمزًا وعنوانًا ومقدارًا صغيرًا من المحتوى النصي. هذا النمط طريقة إنشاء إشعار يمكن للمستخدم النقر عليه لتشغيل أحد الإشعارات نشاطك في تطبيقك.

الشكل 1. إشعار يتضمن رمز وعنوان وبعض النصوص.

لمزيد من التفاصيل حول كل جزء من الإشعار، اطّلِع على مكونات الإشعار.

إعلان إذن التشغيل

يتوافق الإصدار 13 من نظام التشغيل Android (المستوى 33 من واجهة برمجة التطبيقات) والإصدارات الأحدث مع إذن وقت التشغيل للنشر. إشعارات غير مستثناة (بما في ذلك إشعارات الخدمات التي تعمل في المقدّمة) من تطبيق معيّن

يظهر الإذن الذي يجب الإفصاح عنه في ملف بيان تطبيقك. في مقتطف الرمز التالي:

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

للحصول على مزيد من التفاصيل حول أذونات التشغيل، يُرجى الاطّلاع على إذن تشغيل الإشعارات

ضبط محتوى الإشعار

للبدء، يجب ضبط محتوى الإشعار وقناته باستخدام NotificationCompat.Builder الخاص بك. يوضّح المثال التالي كيفية إنشاء إشعار باستخدام التالي:

  • رمز صغير، يتم ضبطه من قِبل setSmallIcon(). وهذا هو المحتوى الوحيد المرئي للمستخدم.

  • عنوان تم ضبطه من قِبل setContentTitle()

  • النص الأساسي، الذي تم تعيينه بواسطة setContentText()

  • أولوية الإشعار، التي يتم ضبطها من خلال setPriority() تحدد الأولوية مدى تداخل الإشعار مع نظام التشغيل Android 7.1 و سابقًا. بالنسبة إلى نظام التشغيل Android 8.0 والإصدارات الأحدث، اضبط أهمية القناة على كما هو موضح في القسم التالي.

Kotlin

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

Java

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

تتطلب منك الدالة الإنشائية NotificationCompat.Builder توفير قناة. رقم التعريف هذا الإجراء مطلوب للتوافق مع Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات) و لاحقًا، ولكن يتم تجاهلها في الإصدارات السابقة.

بشكل تلقائي، يتم اقتطاع المحتوى النصي للإشعار ليلائم سطر واحد. إِنْتَ يمكنك إظهار معلومات إضافية من خلال إنشاء إشعار قابل للتوسيع.

الشكل 2. إشعار قابل للتصغير بصورته المصغرة والموسّعة

إذا أردت أن يكون الإشعار أطول، يمكنك تفعيل إشعار قابل للتوسيع عن طريق إضافة قالب نمط يحتوي على setStyle() على سبيل المثال، تُنشئ التعليمة البرمجية التالية منطقة نص أكبر:

Kotlin

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

Java

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...")
        .setStyle(new NotificationCompat.BigTextStyle()
                .bigText("Much longer text that cannot fit one line..."))
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);

لمزيد من المعلومات عن أنماط الإشعارات الكبيرة الأخرى، بما في ذلك كيفية إضافة صورة وعناصر تحكّم في تشغيل الوسائط، يُرجى الاطّلاع على مقالة إنشاء إشعار قابل للتوسيع .

إنشاء قناة وتحديد أهميتها

لكي تتمكّن من إرسال الإشعار على الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، عليك تسجيل قناة الإشعارات في النظام من خلال تمرير مثيل NotificationChannel إلى createNotificationChannel(). يتم حظر الرمز التالي بواسطة شرط في إصدار SDK_INT:

Kotlin

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)
    }
}

Java

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);
    }
}

وبما أنّه يجب إنشاء قناة الإشعارات قبل نشر أي إعلامات على الإصدار 8.0 من Android والإصدارات الأحدث، عليك تنفيذ هذا الرمز البرمجي فور بدء تطبيقك. من الآمن استدعاء هذا بشكل متكرر، لأن إنشاء صورة قناة الإشعارات لا تنفذ أي عملية.

تتطلّب الدالة الإنشائية NotificationChannel استخدام importance، وذلك باستخدام أحد الثوابت من فئة NotificationManager. هذا النمط كيفية مقاطعة المستخدم لأي إشعار ينتمي إلى هذه القناة. تحديد الأولوية عند استخدام setPriority() للتوافق مع الإصدار 7.1 من Android وأقدمها، كما هو موضح في المثال السابق.

على الرغم من أنّه عليك ضبط أهمية الإشعار أو أولويته كما هو موضّح في المثال التالي، لا يضمن النظام سلوك التنبيه الذي تحصل عليه. في بعض الحالات، قد يغيّر النظام مستوى الأهمية استنادًا إلى عوامل أخرى، ويمكن للمستخدم في أي وقت إعادة تحديد مستوى الأهمية لقناة معيّنة .

لمزيد من المعلومات عن ما تعنيه المستويات المختلفة، يمكنك الاطّلاع على أهمية الإشعار المستويات.

ضبط إجراء النقر على الإشعار

يجب أن يستجيب كل إشعار بنقرة، ويتم ذلك عادةً لفتح نشاط في تطبيق يتوافق مع الإشعار. ولإجراء ذلك، حدِّد هدفًا للمحتوى محدّد باستخدام PendingIntent كائن وتمريره إلى setContentIntent()

يوضِّح المقتطف التالي كيفية إنشاء هدف أساسي لفتح نشاط. عندما ينقر المستخدم على الإشعار:

Kotlin

// Create an explicit intent for an Activity in your app.
val intent = Intent(this, AlertDetails::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
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.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true)

Java

// Create an explicit intent for an Activity in your app.
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
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.
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

يستدعي هذا الرمز setAutoCancel()، ما يؤدي إلى إزالة الإشعار تلقائيًا عندما ينقر المستخدم عليه.

الطريقة setFlags() كما هو موضح في المثال السابق يحافظ على التنقل المتوقع للمستخدم المستخدمين بعد فتح التطبيق من خلال الإشعار. قد ترغب في اعتمادًا على نوع النشاط الذي تبدأه، والذي يمكن أن يكون أحد ما يلي:

لمزيد من المعلومات حول الطرق المختلفة لضبط الغرض من الإشعار، يمكنك الاطّلاع على بدء نشاط من إشعار

عرض الإشعار

لإظهار الإشعار، اتصل NotificationManagerCompat.notify()، وتمريره مُعرّفًا فريدًا للإشعار ونتيجة NotificationCompat.Builder.build() يظهر ذلك في المثال التالي:

Kotlin

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<out String>,
        //                                        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())
}

Java

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 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
   }
   // notificationId is a unique int for each notification that you must define.
   notify(NOTIFICATION_ID, builder.build())
}

احفظ معرّف الإشعار الذي تمنحه لـ "NotificationManagerCompat.notify()". لأنك تحتاج إليها عندما ترغب في تحديث أو إزالة

من أجل اختبار الإشعارات الأساسية على الأجهزة التي تعمل على الإصدار 13 من نظام التشغيل Android والإصدارات الأحدث، يجب تفعيل الإشعارات يدويًا أو إنشاء مربّع حوار إشعارات الطلب.

إضافة أزرار الإجراءات

يمكن أن يعرض الإشعار ما يصل إلى ثلاثة أزرار إجراءات تتيح للمستخدم الردّ. بسرعة، مثل تأجيل تذكير أو الرد على رسالة نصية. لكن هذه يجب ألا تكرر أزرار الإجراءات الإجراء الذي يتم تنفيذه عندما ينقر المستخدم على إشعار.

الشكل 3: إشعار يتضمن وزر إجراء واحد.

لإضافة زر إجراء، مرِّر PendingIntent إلى addAction() . يشبه ذلك إعداد إجراء النقر التلقائي للإشعارات، باستثناء فبدلاً من بدء نشاط ما، يمكنك القيام بأمور أخرى مثل بدء BroadcastReceiver التي يؤدي وظيفة في الخلفية إلى عدم مقاطعة التطبيق مفتوح بالفعل.

على سبيل المثال، يوضح الرمز التالي كيفية إرسال بث إلى جهاز المستلم:

Kotlin


val ACTION_SNOOZE = "snooze"

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)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent)

Java


String ACTION_SNOOZE = "snooze"

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);

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)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

لمزيد من المعلومات حول كيفية إنشاء خلفية "BroadcastReceiver" لتشغيل خلفية العمل، يُرجى مراجعة نظرة عامة على عمليات البث.

إذا كنت تحاول إنشاء إشعار باستخدام أزرار تشغيل الوسائط بدلاً من ذلك، مثل إيقاف المقاطع الصوتية مؤقتًا وتخطيها، للاطلاع على كيفية إنشاء إشعار يتضمن وسائط عناصر التحكم.

إضافة إجراء ردّ مباشر

يتيح إجراء الرد المباشر، الذي تم طرحه في الإصدار Android 7.0 (المستوى 24 من واجهة برمجة التطبيقات)، للمستخدمين إدخال النص مباشرةً في الإشعار يتم بعد ذلك تسليم النص إلى تطبيقك بدون فتح أي نشاط. على سبيل المثال، يمكنك استخدام إجراء رد مباشر للسماح للمستخدمين بالرد على الرسائل النصية أو تحديث قوائم المهام من داخل .

الشكل 4. النقر على "الرد" إلى فتح إدخال النص.

يظهر إجراء الرد المباشر كزر إضافي في الإشعار يتم فتح إدخال نصي. عندما ينتهي المستخدم من الكتابة، يرفق النظام النص للغرض الذي تحدده لإجراء الإشعار ويرسل النية في تطبيقك.

إضافة زر الرد

لإنشاء إجراء إشعار يتيح إمكانية الرد المباشر، اتبع الخطوات التالية:

  1. إنشاء مثيل RemoteInput.Builder التي يمكنك إضافتها إلى إجراء الإشعار تقبل الدالة الإنشائية لهذه الفئة سلسلة يستخدمها النظام كمفتاح لإدخال النص. تطبيقك لاحقًا يستخدم هذا المفتاح لاسترداد نص المدخلات.

    Kotlin

      // Key for the string that's delivered in the action's 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

      // Key for the string that's delivered in the action's intent.
      private static final String KEY_TEXT_REPLY = "key_text_reply";
    
      String replyLabel = getResources().getString(R.string.reply_label);
      RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
              .setLabel(replyLabel)
              .build();
      
  2. إنشاء PendingIntent لإجراء الرد

    Kotlin

      // Build a PendingIntent for the reply action to trigger.
      var replyPendingIntent: PendingIntent =
          PendingIntent.getBroadcast(applicationContext,
              conversation.getConversationId(),
              getMessageReplyIntent(conversation.getConversationId()),
              PendingIntent.FLAG_UPDATE_CURRENT)
      

    Java

      // Build a PendingIntent for the reply action to trigger.
      PendingIntent replyPendingIntent =
              PendingIntent.getBroadcast(getApplicationContext(),
                      conversation.getConversationId(),
                      getMessageReplyIntent(conversation.getConversationId()),
                      PendingIntent.FLAG_UPDATE_CURRENT);
      
  3. إرفاق RemoteInput الاعتراض على إجراء باستخدام addRemoteInput()

    Kotlin

      // Create the reply action and add the remote input.
      var action: NotificationCompat.Action =
          NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
              getString(R.string.label), replyPendingIntent)
              .addRemoteInput(remoteInput)
              .build()
      

    Java

      // Create the reply action and add the remote input.
      NotificationCompat.Action action =
              new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                      getString(R.string.label), replyPendingIntent)
                      .addRemoteInput(remoteInput)
                      .build();
      
  4. يمكنك تطبيق الإجراء على إشعار وإصداره.

    Kotlin

      // Build the notification and add the action.
      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()
    
      // Issue the notification.
      with(NotificationManagerCompat.from(this)) {
          notificationManager.notify(notificationId, newMessageNotification)
      }
      

    Java

      // Build the notification and add the action.
      Notification 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();
    
      // Issue the notification.
      NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
      notificationManager.notify(notificationId, newMessageNotification);
      

يطلب النظام من المستخدم إدخال رد عندما يقوم بتشغيل والإشعار، كما هو موضح في الشكل 4.

استرداد البيانات التي أدخلها المستخدم من الردّ

لتلقّي إدخال المستخدم من واجهة مستخدم الردّ على الإشعار، يمكنك الاتصال بـ RemoteInput.getResultsFromIntent()، مع تضمين Intent الذي تلقّاه BroadcastReceiver:

Kotlin

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

Java

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

بعد معالجة الرسالة النصية، يمكنك تعديل الإشعار من خلال الاتصال. NotificationManagerCompat.notify() تتضمّن رقم التعريف والعلامة نفسيهما، إذا تم استخدامها. هذا هو اللازمة لإخفاء واجهة مستخدم الرد المباشر والتأكيد على أن رده استلامها ومعالجتها بشكل صحيح.

Kotlin

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

Java

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

عند التعامل مع هذا الإشعار الجديد، يمكنك استخدام السياق الذي تم تمريره إلى الْمُسْتَلِمْ onReceive() .

يمكنك إلحاق الرد أسفل الإشعار من خلال الاتصال setRemoteInputHistory() ومع ذلك، إذا كنت تنشئ تطبيق مراسلة، فأنشئ نمطًا للمراسلة الإشعار وإلحاق رسالة جديدة إلى المحادثة.

لمزيد من النصائح بشأن الإشعارات من أحد تطبيقات المراسلة، راجِع القسم حول أفضل الممارسات لتطبيقات المراسلة

إضافة شريط تقدّم

يمكن أن تتضمَّن الإشعارات مؤشر تقدّم متحركًا يُظهر للمستخدمين حالة عملية جارية.

الشكل 5. شريط التقدم أثناء لعملية ما.

إذا كان بإمكانك تقدير مقدار اكتمال العملية في أي وقت، فاستخدم "التحديد" شكل المؤشر - كما هو موضح في الشكل 5 - من خلال استدعاء setProgress(max, progress, false) المعلمة الأولى هي ما تشير إليه تفاصيل مثل 100. والثاني هو ومدى اكتمال العملية. تشير النتيجة الأخيرة إلى أن هذا تقدم محدد الشريط.

أثناء إجراء العملية، اتصِل باستمرار برقم "setProgress(max, progress, false)" مع تقديم قيمة معدّلة لـ "progress" وأعِد إصدار الإشعار، وفقًا لما يلي: كما هو موضح في المثال التالي.

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentTitle("Picture Download")
    setContentText("Download in progress")
    setSmallIcon(R.drawable.ic_notification)
    setPriority(NotificationCompat.PRIORITY_LOW)
}
val PROGRESS_MAX = 100
val PROGRESS_CURRENT = 0
NotificationManagerCompat.from(this).apply {
    // Issue the initial notification with zero progress.
    builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false)
    notify(notificationId, builder.build())

    // Do the job that tracks the progress here.
    // Usually, this is in a worker thread.
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, builder.build());

    // When done, update the notification once more to remove the progress bar.
    builder.setContentText("Download complete")
            .setProgress(0, 0, false)
    notify(notificationId, builder.build())
}

Java

...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);

// Issue the initial notification with zero progress.
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, builder.build());

// Do the job that tracks the progress here.
// Usually, this is in a worker thread.
// To show progress, update PROGRESS_CURRENT and update the notification with:
// builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
// notificationManager.notify(notificationId, builder.build());

// When done, update the notification once more to remove the progress bar.
builder.setContentText("Download complete")
        .setProgress(0,0,false);
notificationManager.notify(notificationId, builder.build());

في نهاية العملية، يجب أن يساوي progress max. يمكنك مغادرة شريط التقدم لتوضيح أن العملية قد تمت أو إزالتها. في كلتا الحالتين، تعديل نص الإشعار لتوضيح أن العملية قد اكتملت. لإزالة شريط التقدم، اطلب setProgress(0, 0, false).

عرض شريط تقدم غير محدد (شريط لا يشير إلى الاكتمال نسبة مئوية)، اتصل بالرقم setProgress(0, 0, true). النتيجة هي مؤشر يحتوي على نفس نمط شريط التقدم السابق باستثناء أنه إكمال رسم متحرك لا يشير إلى الاكتمال. يتم تشغيل الرسوم المتحركة للتقدم حتى تتصل برقم setProgress(0, 0, false) ثم عدِّل الإشعار لإزالة مؤشر النشاط.

احرص على تغيير نص الإشعار للإشارة إلى اكتمال العملية.

ضبط فئة على مستوى النظام

يستخدم Android فئات محددة مسبقًا على مستوى النظام لتحديد ما إذا كان يجب الإزعاج المستخدم من خلال إشعار محدد عندما يفعّل المستخدم ميزة عدم الإزعاج .

إذا كان الإشعار يندرج ضمن إحدى فئات الإشعارات المحددة في NotificationCompat - مثل CATEGORY_ALARM, CATEGORY_REMINDER, CATEGORY_EVENT, أو CATEGORY_CALL— بيان على هذا النحو من خلال تمرير الفئة المناسبة إلى setCategory():

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE)

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setCategory(NotificationCompat.CATEGORY_MESSAGE);

يستخدم النظام هذه المعلومات حول فئة الإشعار لإجراء ما يلي: القرارات المتعلقة بعرض الإشعار عندما يكون الجهاز في وضع عدم النشاط الإزعاج ومع ذلك، لا يلزمك ضبط فئة على مستوى النظام. إجراء ذلك فقط إذا كانت الإشعارات تتطابق مع إحدى الفئات المحددة في NotificationCompat

عرض رسالة عاجلة

قد يحتاج تطبيقك إلى عرض رسالة عاجلة لفترة محدودة، مثل مكالمة هاتفية واردة أو تنبيه يرنّ. في هذه المواقف، يمكنك ربط الإذن بالعرض ملء الشاشة مع الإشعار

عند تشغيل الإشعار، تظهر للمستخدمين إحدى الحالتَين التاليتَين، استنادًا إلى حالة قفل الجهاز:

  • إذا تم قفل جهاز المستخدم، فسيظهر نشاط بملء الشاشة، يغطّي وقفل الشاشة.
  • إذا تم فتح قفل جهاز المستخدم، يظهر الإشعار في نافذة موسّعة. يتضمن خيارات لمعالجة الإشعار أو رفضه.

يوضّح المقتطف البرمجي التالي كيفية ربط إشعارك بمحاولة عرض بملء الشاشة:

Kotlin

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)
        .setFullScreenIntent(fullScreenPendingIntent, true)

Java

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)
        .setFullScreenIntent(fullScreenPendingIntent, true);

ضبط إذن الوصول إلى شاشة القفل

للتحكّم في مستوى التفاصيل المرئية في الإشعار من شاشة القفل، مكالمة setVisibility() وحدد إحدى القيم التالية:

  • VISIBILITY_PUBLIC: سيظهر المحتوى الكامل للإشعارات على شاشة القفل.

  • VISIBILITY_SECRET: عدم ظهور أي جزء من الإشعار على شاشة القفل

  • VISIBILITY_PRIVATE: المعلومات الأساسية فقط، مثل رمز الإشعار والمحتوى يظهر على شاشة القفل. المحتوى الكامل في الإشعار غير بَرْنَامَجْ تِلِفِزْيُونِي.

عند ضبط VISIBILITY_PRIVATE، يمكنك أيضًا توفير إصدار بديل من محتوى الإشعار الذي يخفي تفاصيل معينة. فعلى سبيل المثال، أحد تطبيقات الرسائل القصيرة SMS إشعار يعرض الرسالة "لديك 3 رسائل نصية جديدة"، لكن يخفي محتوى الرسالة والمُرسِلين. لتوفير هذا البديل إشعار: يمكنك أولاً إنشاء إشعار بديل باستخدام NotificationCompat.Builder كالعادة. بعد ذلك، إرفاق الإشعار البديل إلى الإشعار العادي عبر setPublicVersion()

ضع في اعتبارك أن المستخدم لديه دائمًا التحكم النهائي في ما إذا كان تكون الإشعارات مرئية على شاشة القفل ويمكنك التحكّم فيها استنادًا إلى وقنوات الإشعارات في التطبيق.

تعديل إشعار

لتعديل إشعار بعد إصداره، يُرجى الاتصال NotificationManagerCompat.notify() مجددًا، مع إدخال رقم التعريف نفسه الذي استخدمته من قبل. إذا تم إغلاق الإشعار السابق، سيتم إنشاء إشعار جديد. بدلاً من ذلك.

يمكنك اختياريًا استدعاء setOnlyAlertOnce() لكي يقاطع الإشعار المستخدم، سواء من خلال الصوت أو الاهتزاز أو المرئيات في المرة الأولى فقط التي يظهر فيها الإشعار وليس لوقت لاحق التحديثات.

إزالة إشعار

تظل الإشعارات مرئية إلى أن يحدث أحد الإجراءَين التاليَين:

  • يستبعد المستخدم الإشعار.
  • ينقر المستخدم على الإشعار، في حال الاتصال بـ setAutoCancel() عند الاتصال إنشاء الإشعار.
  • يمكنك الاتصال برقم cancel() للحصول على معرّف إشعار معيّن. تؤدي هذه الطريقة أيضًا إلى حذف البيانات الحالية الإشعارات.
  • يمكنك الاتصال بـ cancelAll()، لإزالة جميع الإشعارات التي أصدرتَها في السابق.
  • تنقضي المدة المحددة، في حالة تعيين مهلة عند إنشاء باستخدام setTimeoutAfter() يمكنك إلغاء إشعار قبل انقضاء مهلة الانتظار المحدّدة .

أفضل الممارسات لتطبيقات المراسلة

ننصحك باتّباع أفضل الممارسات الواردة هنا عند إنشاء إشعارات وتطبيقات المراسلة والدردشة.

استخدام MessagingStyle

بدءًا من الإصدار 7.0 من نظام التشغيل Android (المستوى 24 من واجهة برمجة التطبيقات)، سيوفّر Android نمط إشعارات. مخصص لمحتوى المراسلة. باستخدام NotificationCompat.MessagingStyle يمكنك تغيير العديد من التصنيفات المعروضة في الإشعار، بما في ذلك عنوان المحادثة والرسائل الإضافية وعرض المحتوى الإشعار.

يوضح مقتطف الرمز التالي كيفية تخصيص نمط إشعار. باستخدام الفئة MessagingStyle.

Kotlin

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

Java

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

بدءًا من الإصدار 9.0 من نظام التشغيل Android (المستوى 28 من واجهة برمجة التطبيقات)، يجب أيضًا استخدام Person من أجل الحصول على العرض الأمثل للإشعار وصوره الرمزية.

عند استخدام "NotificationCompat.MessagingStyle"، اتّبِع الخطوات التالية:

  • اضغط على رمز المكالمة MessagingStyle.setConversationTitle() لتحديد عنوان للمحادثات الجماعية التي تضم أكثر من شخصَين. جيدة وقد يكون عنوان المحادثة اسم المحادثة الجماعية، أو إذا لم يكن كذلك يكون لها اسم وقائمة بالمشاركين في المحادثة. بدون ذلك، قد يتم الخلط بين الرسالة على أنها تنتمي إلى محادثة فردية مع مرسل أحدث رسالة في المحادثة.
  • يمكنك استخدام MessagingStyle.setData() لتضمين رسائل الوسائط مثل الصور. أنواع MIME للنمط image/* متاحة.

استخدام ميزة "الرد المباشر"

تتيح ميزة "الرد المباشر" للمستخدم الرد المضمّن على الرسالة.

  • بعد أن يردّ المستخدم باستخدام إجراء الرد المضمّن، يمكنك استخدام MessagingStyle.addMessage() لتعديل إشعار MessagingStyle، وعدم سحب الإشعار أو إلغائه . يؤدي عدم إلغاء الإشعار إلى السماح للمستخدم بإرسال عدة رسائل الردود من الإشعار.
  • لجعل إجراء الرد المضمّن متوافقًا مع Wear OS، يمكنك إجراء مكالمة Action.WearableExtender.setHintDisplayInlineAction(true)
  • يمكنك استخدام addHistoricMessage() لتوفير سياق في محادثة رد مباشر عن طريق إضافة إرسال رسالة إلى الإشعار.

تفعيل ميزة "الرد السريع"

  • لتفعيل ميزة "الرد السريع"، يُرجى الاتصال setAllowGeneratedResponses(true) على إجراء الرد. يؤدي ذلك إلى إتاحة ردود ميزة "الرد السريع" لـ المستخدمين عند ربط الإشعار بجهاز Wear OS الرد السريع يتم إنشاء الردود من خلال نموذج التعلم الآلي بالكامل على الساعة باستخدام السياق المقدّم من NotificationCompat.MessagingStyle ولا يتم تحميل أي بيانات على الإنترنت لإنشاء الردود.

إضافة البيانات الوصفية للإشعارات