Создать уведомление

Notifications provide short, timely information about events in your app while it isn't in use. This document shows you how to create a notification with various features. For an introduction to how notifications appear on Android, see the Notifications overview . For sample code that uses notifications, see the SociaLite sample on GitHub.

The code in this page uses the NotificationCompat APIs from the AndroidX Library. These APIs let you add features available only on newer versions of Android while still providing compatibility back to Android 9 (API level 28). However, some features, such as the inline reply action, result in a no-op on earlier versions.

Создать простое уведомление

A notification in its most basic and compact form—also known as collapsed form —displays an icon, a title, and a small amount of text content. This section shows how to create a notification that the user can tap to launch an activity in your app.

Рисунок 1. Уведомление со значком, заголовком и текстом.

Для получения более подробной информации о каждой части уведомления ознакомьтесь с разделом «Анатомия уведомления» .

Объявите разрешение во время выполнения.

Android 13 (уровень API 33) и выше поддерживают разрешение во время выполнения для отправки уведомлений, не подпадающих под исключения (включая уведомления от служб переднего плана (FGS)), из приложения.

Необходимые для указания в файле манифеста вашего приложения разрешения приведены в следующем фрагменте кода:

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

Для получения более подробной информации о разрешениях во время выполнения см. раздел «Разрешения во время выполнения уведомлений» .

Настройте содержимое уведомления

Для начала задайте содержимое уведомления и канал, используя объект NotificationCompat.Builder . В следующем примере показано, как создать уведомление со следующими параметрами:

  • Небольшая иконка, устанавливаемая функцией setSmallIcon() . Это единственный контент, видимый пользователю, который является обязательным.

  • Заголовок, устанавливаемый функцией setContentTitle() .

  • Основной текст, устанавливаемый функцией setContentText() .

  • The notification priority, set by setPriority() . The priority determines how intrusive the notification is on Android 7.1 and earlier. For Android 8.0 and later, instead set the channel importance as shown in the next section.

Котлин

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

The NotificationCompat.Builder constructor requires you to provide a channel ID. This is required for compatibility with Android 8.0 (API level 26) and later, but is ignored by earlier versions.

По умолчанию текст уведомления обрезается до одной строки. Вы можете отобразить дополнительную информацию, создав раскрывающееся уведомление.

Рисунок 2. Разворачиваемое уведомление в свернутом и развернутом виде.

Если вы хотите, чтобы ваше уведомление было длиннее, вы можете включить расширяемое уведомление, добавив шаблон стиля с помощью 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)

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

Для получения дополнительной информации о других стилях больших уведомлений, включая добавление изображения и элементов управления воспроизведением мультимедиа, см. раздел «Создание расширяемого уведомления» .

Создайте канал и установите уровень важности.

Before you can deliver the notification on Android 8.0 and later, register your app's notification channel with the system by passing an instance of NotificationChannel to createNotificationChannel() . The following code is blocked by a condition on the SDK_INT version:

Котлин

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

Because you must create the notification channel before posting any notifications on Android 8.0 and later, execute this code as soon as your app starts. It's safe to call this repeatedly, because creating an existing notification channel performs no operation.

The NotificationChannel constructor requires an importance , using one of the constants from the NotificationManager class. This parameter determines how to interrupt the user for any notification that belongs to this channel. Set the priority with setPriority() to support Android 7.1 and earlier, as shown in the preceding example.

Although you must set the notification importance or priority as shown in the following example, the system doesn't guarantee the alert behavior you get. In some cases, the system might change the importance level based on other factors, and the user can always redefine what the importance level is for a given channel.

Для получения более подробной информации о значении различных уровней ознакомьтесь с информацией об уровнях важности уведомлений .

Настройте действие нажатия для уведомления.

Every notification must respond to a tap, usually to open an activity in your app that corresponds to the notification. To do so, specify a content intent defined with a PendingIntent object and pass it to 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)

Java

// 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() , который автоматически удаляет уведомление, когда пользователь нажимает на него.

The intent flags in the preceding example preserve the user's expected navigation experience after the user opens your app using the notification. You might want to use it depending on the type of activity you're starting, which can be one of the following:

  • An activity that exists exclusively for responses to the notification. There's no reason the user navigates to this activity during normal app use, so the activity starts a new task instead of being added to your app's existing task and back stack . This is the type of intent created in the preceding sample.

  • Активность, которая является частью стандартного рабочего процесса вашего приложения. В данном случае запуск активности создает стек возврата, чтобы сохранить ожидания пользователя относительно кнопок «Назад» и «Вверх» .

Более подробную информацию о различных способах настройки намерения уведомления см. в разделе «Запуск действия из уведомления» .

Показать уведомление

To make the notification appear, call NotificationManagerCompat.notify() , passing it a unique ID for the notification and the result of NotificationCompat.Builder.build() . This is shown in the following example:

Котлин

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

Java

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() , поскольку он понадобится вам при обновлении или удалении уведомления .

Кроме того, для проверки работы базовых уведомлений на устройствах под управлением Android 13 и выше включите уведомления вручную или создайте диалоговое окно для запроса уведомлений.

Добавить кнопки действий

A notification can offer up to three action buttons that let the user respond quickly, such as to snooze a reminder or to reply to a text message. But these action buttons must not duplicate the action performed when the user taps the notification .

Рисунок 3. Уведомление с одной кнопкой действия.

To add an action button, pass a PendingIntent to the addAction() method. This is like setting up the notification's default tap action, except instead of launching an activity, you can do other things such as start a BroadcastReceiver that performs a job in the background so that the action doesn't interrupt the app that's already open.

Например, следующий код показывает, как отправить широковещательное сообщение конкретному получателю:

Котлин

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>

Java

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 .

Если же вы пытаетесь создать уведомление с кнопками воспроизведения мультимедиа, например, для паузы и пропуска треков, см. раздел о создании уведомления с элементами управления воспроизведением мультимедиа .

Добавить действие прямого ответа

The direct reply action, introduced in Android 7.0 (API level 24), lets users enter text directly into the notification. The text is then delivered to your app without opening an activity. For example, you can use a direct reply action to let users reply to text messages or update task lists from within the notification.

Рисунок 4. Нажатие кнопки «Ответить» открывает текстовое поле.

The direct reply action appears as an additional button in the notification that opens a text input. When the user finishes typing, the system attaches the text response to the intent you specify for the notification action and sends the intent to your app.

Добавьте кнопку ответа

Чтобы создать действие уведомления, поддерживающее прямой ответ, выполните следующие действия:

  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"; String replyLabel = getResources().getString(R.string.reply_label); RemoteInput 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 // Создайте уведомление и добавьте действие. 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(); // Выпустить уведомление. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, newMessageNotification); ```

Система запрашивает у пользователя ввод ответа при срабатывании уведомления, как показано на рисунке 4.

Получить ввод пользователя из ответа

Чтобы получить ввод от пользователя через пользовательский интерфейс ответа на уведомление, вызовите метод RemoteInput.getResultsFromIntent() , передав ему Intent полученный вашим BroadcastReceiver :

Котлин

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

After you process the text, update the notification by calling NotificationManagerCompat.notify() with the same ID and tag, if used. This is necessary to hide the direct reply UI and confirm to the user that their reply is received and processed correctly.

Котлин

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

Получить другие данные

Обработка других типов данных осуществляется аналогично с помощью 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() получателя.

Append the reply to the bottom of the notification by calling setRemoteInputHistory() . However, if you're building a messaging app, create a messaging-style notification and append the new message to the conversation.

Дополнительные рекомендации по настройке уведомлений от мессенджеров см. в разделе о лучших практиках использования мессенджеров .

Показать срочное сообщение

Your app might need to display an urgent, time-sensitive message, such as an incoming phone call or a ringing alarm. In these situations, you can associate a full-screen intent with your notification.

При срабатывании уведомления пользователи видят одно из следующих изображений, в зависимости от состояния блокировки устройства:

  • Если устройство пользователя заблокировано, на весь экран отображается сообщение, закрывающее экран блокировки.
  • Если устройство пользователя разблокировано, уведомление отображается в развернутом виде, включая параметры для обработки или отклонения уведомления.

Следующий фрагмент кода демонстрирует, как связать уведомление с полноэкранным интентом:

Котлин

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>

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

Установить видимость экрана блокировки

Чтобы управлять уровнем детализации, отображаемой в уведомлении на экране блокировки, вызовите setVisibility() и укажите одно из следующих значений:

  • VISIBILITY_PUBLIC : полное содержимое уведомления отображается на экране блокировки.

  • VISIBILITY_SECRET : ни одна часть уведомления не отображается на экране блокировки.

  • VISIBILITY_PRIVATE : на экране блокировки отображается только основная информация, такая как значок уведомления и заголовок содержимого. Полное содержимое уведомления не отображается.

При установке параметра VISIBILITY_PRIVATE вы также можете предоставить альтернативную версию содержимого уведомления, которая скрывает определенные детали. Например, приложение для SMS может отображать уведомление «У вас 3 новых текстовых сообщения», но скрывать содержимое сообщений и отправителей. Чтобы предоставить такое альтернативное уведомление, сначала создайте альтернативное уведомление с помощью NotificationCompat.Builder , как обычно. Затем прикрепите альтернативное уведомление к обычному уведомлению с помощью setPublicVersion() .

Следует помнить, что пользователь всегда имеет полный контроль над тем, будут ли его уведомления отображаться на экране блокировки, и может управлять ими в зависимости от каналов уведомлений вашего приложения.

Обновить уведомление

To update a notification after you issue it, call NotificationManagerCompat.notify() again, passing it the same ID you used before. If the previous notification is dismissed, a new notification is created instead.

You can optionally call setOnlyAlertOnce() so your notification interrupts the user—with sound, vibration, or visual clues—only the first time the notification appears and not for later updates.

Удалить уведомление

Уведомления остаются видимыми до тех пор, пока не произойдет одно из следующих событий:

  • Пользователь отклоняет уведомление.
  • Пользователь нажимает на уведомление, если вы вызываете setAutoCancel() при его создании.
  • Вызов метода cancel() предназначен для конкретного идентификатора уведомления. Этот метод также удаляет текущие уведомления.
  • Вы вызываете cancelAll() , который удаляет все ранее отправленные вами уведомления.
  • The specified duration elapses, if you set a timeout when creating the notification, using setTimeoutAfter() . If required, you can cancel a notification before the specified timeout duration elapses.

Рекомендации по использованию мессенджеров

При создании уведомлений для ваших приложений для обмена сообщениями и чата учитывайте приведенные здесь рекомендации.

Используйте MessagingStyle

Starting in Android 7.0 (API level 24), Android provides a notification style template specifically for messaging content. Using the NotificationCompat.MessagingStyle class, you can change several of the labels displayed on the notification, including the conversation title, additional messages, and the content view for the notification.

Приведённый ниже фрагмент кода демонстрирует, как настроить стиль уведомления с помощью класса 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()

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

Начиная с Android 9.0 (уровень API 28), для оптимального отображения уведомления и его аватаров также необходимо использовать класс Person .

При использовании NotificationCompat.MessagingStyle выполните следующие действия:

  • Вызовите MessagingStyle.setConversationTitle() , чтобы установить заголовок для групповых чатов с участием более двух человек. Хорошим заголовком для беседы может быть название группового чата или, если у него нет названия, список участников беседы. Без этого сообщение может быть ошибочно принято за сообщение, отправленное один на один отправителю последнего сообщения в беседе.
  • Для включения медиасообщений, таких как изображения, используйте метод MessagingStyle.setData() . Поддерживаются MIME-типы с шаблоном image/*.

Используйте прямой ответ

Функция «Прямой ответ» позволяет пользователю ответить на сообщение непосредственно в тексте.

  • After a user replies with the inline reply action, use MessagingStyle.addMessage() to update the MessagingStyle notification, and don't retract or cancel the notification. Not cancelling the notification lets the user send multiple replies from the notification.
  • Чтобы обеспечить совместимость действия «Встроенный ответ» с Wear OS, вызовите Action.WearableExtender.setHintDisplayInlineAction(true) .
  • Используйте метод addHistoricMessage() , чтобы добавить контекст к диалогу с прямым ответом, включив в уведомление исторические сообщения.

Включить функцию «Умный ответ»

  • Чтобы включить функцию Smart Reply, вызовите setAllowGeneratedResponses(true) в действии ответа. Это позволит пользователям получать ответы Smart Reply при передаче уведомления на устройство Wear OS. Ответы Smart Reply генерируются полностью внутричасовой моделью машинного обучения с использованием контекста, предоставляемого уведомлением NotificationCompat.MessagingStyle , и никакие данные не загружаются в интернет для генерации ответов.

Добавить метаданные уведомления