Уведомления предоставляют краткую и актуальную информацию о событиях в вашем приложении, когда оно не используется. В этом документе показано, как создать уведомление с различными функциями. Введение в отображение уведомлений на Android см. в разделе «Обзор уведомлений» . Пример кода, использующего уведомления, можно найти в примере SociaLite на GitHub.
Код на этой странице использует API NotificationCompat
из библиотеки AndroidX. Эти API позволяют добавлять функции, доступные только в новых версиях Android, сохраняя при этом совместимость с Android 9 (уровень API 28). Однако некоторые функции, например, встроенный ответ, приводят к ошибке в более ранних версиях.
Добавьте библиотеку AndroidX Core
Хотя большинство проектов, созданных с помощью Android Studio, включают необходимые зависимости для использования NotificationCompat
, убедитесь, что файл build.gradle
на уровне модуля включает следующую зависимость:
Круто
dependencies { implementation "androidx.core:core-ktx:1.16.0" }
Котлин
dependencies { implementation("androidx.core:core-ktx:1.16.0") }
Создать базовое уведомление
Уведомление в своей самой простой и компактной форме, также известной как свёрнутая форма , отображает значок, заголовок и небольшой текстовый контент. В этом разделе показано, как создать уведомление, нажатие на которое пользователь может запустить действие в вашем приложении.
Рисунок 1. Уведомление со значком, заголовком и текстом.
Более подробную информацию о каждой части уведомления можно найти в статье «Анатомия уведомления» .
Объявите разрешение на выполнение
Android 13 (уровень API 33) и выше поддерживает разрешение времени выполнения для публикации неисключенных (включая Foreground Services (FGS)) уведомлений из приложения.
Разрешение, которое вам необходимо объявить в файле манифеста вашего приложения, представлено в следующем фрагменте кода:
<manifest ...> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application ...> ... </application> </manifest>
Более подробную информацию о разрешениях времени выполнения см. в разделе Разрешение времени выполнения уведомлений .
Установить содержание уведомления
Для начала задайте содержимое и канал уведомления с помощью объекта NotificationCompat.Builder
. В следующем примере показано, как создать уведомление с помощью:
Маленький значок, устанавливаемый функцией
setSmallIcon()
. Это единственный обязательный контент, видимый пользователю.Заголовок, устанавливаемый с помощью
setContentTitle()
.Основной текст, задаваемый
setContentText()
.Приоритет уведомления, устанавливаемый функцией
setPriority()
. Приоритет определяет навязчивость уведомления в Android 7.1 и более ранних версиях. Для Android 8.0 и более поздних версий вместо этого задайте важность канала, как показано в следующем разделе.
Котлин
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
требует указать идентификатор канала. Это необходимо для совместимости с Android 8.0 (уровень API 26) и более поздними версиями, но игнорируется более ранними версиями.
По умолчанию текст уведомления обрезается до одной строки. Вы можете отобразить дополнительную информацию, создав раскрывающееся уведомление.
Рисунок 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...") .setStyle(NotificationCompat.BigTextStyle() .bigText("Much longer text that cannot fit one line...")) .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...") .setStyle(new NotificationCompat.BigTextStyle() .bigText("Much longer text that cannot fit one line...")) .setPriority(NotificationCompat.PRIORITY_DEFAULT);
Дополнительные сведения о других стилях больших уведомлений, в том числе о том, как добавить изображение и элементы управления воспроизведением мультимедиа, см. в разделе Создание расширяемого уведомления .
Создайте канал и установите важность
Прежде чем отправлять уведомления на Android 8.0 и более поздних версиях, зарегистрируйте канал уведомлений вашего приложения в системе, передав экземпляр 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); } }
Поскольку на Android 8.0 и более поздних версиях необходимо создать канал уведомлений перед отправкой любых уведомлений, выполните этот код сразу после запуска приложения. Вы можете вызывать его повторно, поскольку создание существующего канала уведомлений не требует никаких действий.
Конструктору NotificationChannel
требуется параметр importance
, использующий одну из констант класса NotificationManager
. Этот параметр определяет, как прерывать пользователя для любого уведомления, принадлежащего этому каналу. Установите приоритет с помощью setPriority()
для поддержки Android 7.1 и более ранних версий, как показано в предыдущем примере.
Хотя необходимо задать важность или приоритет уведомления, как показано в следующем примере, система не гарантирует ожидаемого поведения оповещения. В некоторых случаях система может изменить уровень важности в зависимости от других факторов, и пользователь всегда может переопределить уровень важности для конкретного канала.
Более подробную информацию о том, что означают различные уровни, можно найти в разделе об уровнях важности уведомлений .
Установите действие при нажатии на уведомление
Каждое уведомление должно реагировать на нажатие, обычно открывая действие в приложении, соответствующее уведомлению. Для этого укажите намерение контента, определяемое объектом PendingIntent
, и передайте его методу setContentIntent()
.
В следующем фрагменте показано, как создать базовое намерение открыть действие, когда пользователь нажимает на уведомление:
Котлин
// 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)
Ява
// 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()
, который автоматически удаляет уведомление, когда пользователь нажимает на него.
Флаги намерений в предыдущем примере сохраняют ожидаемый опыт навигации пользователя после того, как он откроет ваше приложение с помощью уведомления. Вы можете использовать их в зависимости от типа запускаемого действия, которое может быть одним из следующих:
Активность, существующая исключительно для ответов на уведомление. Пользователю не нужно переходить к этой активности во время обычного использования приложения, поэтому эта активность запускает новую задачу, а не добавляется к существующей задаче и стеку переходов вашего приложения. Именно этот тип намерения был создан в предыдущем примере.
Активность, существующая в обычном потоке работы вашего приложения. В этом случае запуск активности создаёт стек переходов назад, чтобы сохранить ожидания пользователя относительно кнопок «Назад» и «Вверх» .
Дополнительную информацию о различных способах настройки цели уведомления см. в разделе Запуск действия из уведомления .
Показать уведомление
Чтобы отобразить уведомление, вызовите метод 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<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()) }
Ява
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()
, так как он понадобится вам, когда вы захотите обновить или удалить уведомление .
Кроме того, чтобы протестировать базовые уведомления на устройствах под управлением Android 13 и выше, включите уведомления вручную или создайте диалоговое окно для запроса уведомлений.
Добавить кнопки действий
Уведомление может содержать до трёх кнопок действий, позволяющих пользователю быстро отреагировать, например, отложить напоминание или ответить на текстовое сообщение. Однако эти кнопки действий не должны дублировать действие, выполняемое при нажатии пользователем на уведомление .
Рисунок 3. Уведомление с одной кнопкой действия.
Чтобы добавить кнопку действия, передайте PendingIntent
методу addAction()
. Это похоже на настройку действия по умолчанию при нажатии на уведомление, но вместо запуска действия вы можете выполнить другие действия, например, запустить BroadcastReceiver
, который выполняет задачу в фоновом режиме, чтобы действие не прерывало работу уже открытого приложения.
Например, следующий код показывает, как отправить трансляцию определенному получателю:
Котлин
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)
Ява
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 (API уровня 24), позволяет пользователям вводить текст непосредственно в уведомление. Затем текст доставляется в ваше приложение без открытия активности. Например, вы можете использовать функцию прямого ответа, чтобы позволить пользователям отвечать на текстовые сообщения или обновлять списки задач прямо из уведомления.
Рисунок 4. Нажатие кнопки «Ответить» открывает поле для ввода текста.
Действие прямого ответа отображается в уведомлении как дополнительная кнопка, открывающая поле ввода текста. Когда пользователь заканчивает ввод, система прикрепляет текстовый ответ к намерению, указанному вами для действия уведомления, и отправляет это намерение в ваше приложение.
Добавить кнопку ответа
Чтобы создать действие уведомления, поддерживающее прямой ответ, выполните следующие действия:
- Создайте экземпляр
RemoteInput.Builder
, который можно добавить в действие уведомления. Конструктор этого класса принимает строку, которую система использует в качестве ключа для ввода текста. Ваше приложение впоследствии использует этот ключ для получения текста ввода.Котлин
// 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() }
Ява
// 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();
- Создайте
PendingIntent
для действия ответа.Котлин
// Build a PendingIntent for the reply action to trigger. var replyPendingIntent: PendingIntent = PendingIntent.getBroadcast(applicationContext, conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT)
Ява
// Build a PendingIntent for the reply action to trigger. PendingIntent replyPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), conversation.getConversationId(), getMessageReplyIntent(conversation.getConversationId()), PendingIntent.FLAG_UPDATE_CURRENT);
- Прикрепите объект
RemoteInput
к действию с помощьюaddRemoteInput()
.Котлин
// 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()
Ява
// 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();
- Примените действие к уведомлению и опубликуйте уведомление.
Котлин
// 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) }
Ява
// 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
:
Котлин
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);
При работе с этим новым уведомлением используйте контекст, переданный методу onReceive()
получателя.
Добавьте ответ в конец уведомления, вызвав метод setRemoteInputHistory()
. Однако, если вы разрабатываете приложение для обмена сообщениями, создайте уведомление в стиле обмена сообщениями и добавьте новое сообщение в беседу.
Дополнительные рекомендации по уведомлениям от приложений для обмена сообщениями см. в разделе о рекомендациях по работе с приложениями для обмена сообщениями .
Показать срочное сообщение
Вашему приложению может потребоваться отобразить срочное сообщение, например, входящий телефонный звонок или сигнал будильника. В таких ситуациях вы можете связать с уведомлением намерение полноэкранного отображения.
При вызове уведомления пользователи видят одно из следующих сообщений в зависимости от статуса блокировки устройства:
- Если устройство пользователя заблокировано, на экране блокировки отображается полноэкранное действие.
- Если устройство пользователя разблокировано, уведомление отображается в развернутом виде, включающем варианты обработки или закрытия уведомления.
В следующем фрагменте кода показано, как связать уведомление с намерением полноэкранного просмотра:
Котлин
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)
Ява
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()
. При необходимости вы можете отменить уведомление до истечения указанного тайм-аута.
Лучшие практики для приложений обмена сообщениями
При создании уведомлений для приложений обмена сообщениями и чата учитывайте перечисленные здесь рекомендации.
Использовать стиль сообщений
Начиная с Android 7.0 (уровень API 24), Android предоставляет шаблон стиля уведомлений, специально предназначенный для содержимого сообщений. С помощью класса 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();
Начиная с Android 9.0 (уровень API 28), для оптимальной визуализации уведомления и его аватаров также требуется использовать класс Person
.
При использовании NotificationCompat.MessagingStyle
выполните следующие действия:
- Вызовите
MessagingStyle.setConversationTitle()
, чтобы задать заголовок для групповых чатов с более чем двумя участниками. Хорошим заголовком для беседы может быть название группового чата или, если у него нет названия, список участников беседы. Без этого сообщение может быть ошибочно принято за принадлежащее индивидуальному разговору с отправителем последнего сообщения в беседе. - Используйте метод
MessagingStyle.setData()
для включения медиасообщений, таких как изображения. Поддерживаются MIME-типы шаблона image/*.
Использовать прямой ответ
Функция «Прямой ответ» позволяет пользователю отвечать непосредственно на сообщение.
- После того, как пользователь ответит с помощью встроенного действия «Ответить», обновите уведомление
MessagingStyle
с помощьюMessagingStyle.addMessage()
и не отзывайте и не отменяйте уведомление. Если уведомление не будет отменено, пользователь сможет отправлять несколько ответов из него. - Чтобы сделать действие встроенного ответа совместимым с Wear OS, вызовите
Action.WearableExtender.setHintDisplayInlineAction(true)
. - Используйте метод
addHistoricMessage()
, чтобы предоставить контекст для прямого ответа, добавив исторические сообщения в уведомление.
Включить умный ответ
- Чтобы включить функцию Smart Reply, вызовите
setAllowGeneratedResponses(true)
в действии «ответить». Это сделает ответы Smart Reply доступными пользователям при отправке уведомления на устройство Wear OS. Ответы Smart Reply генерируются полностью на часах с помощью модели машинного обучения, используя контекст, предоставленный уведомлениемNotificationCompat.MessagingStyle
, и никакие данные не загружаются в интернет для генерации ответов.
Добавить метаданные уведомления
- Назначьте метаданные уведомлений, чтобы сообщить системе, как обрабатывать уведомления вашего приложения, когда устройство находится в
Do Not Disturb mode
. Например, используйте методaddPerson()
илиsetCategory(Notification.CATEGORY_MESSAGE)
, чтобы переопределить режим «Не беспокоить».