Уведомления предоставляют краткую и своевременную информацию о событиях в вашем приложении, когда оно не используется. В этом документе показано, как создать уведомление с различными функциями. Введение в то, как уведомления отображаются на Android, см. в разделе «Обзор уведомлений» . Пример кода, использующего уведомления, см. в примере SociaLite на GitHub.
Код на этой странице использует API NotificationCompat из библиотеки AndroidX. Эти API позволяют добавлять функции, доступные только в более новых версиях Android, обеспечивая при этом совместимость с Android 9 (уровень API 28). Однако некоторые функции, такие как встроенный ответ, в более ранних версиях не выполняют никаких действий.
Создать простое уведомление
Уведомление в своей самой простой и компактной форме — также известной как свернутая форма — отображает значок, заголовок и небольшой текстовый контент. В этом разделе показано, как создать уведомление, которое пользователь может нажать, чтобы запустить действие в вашем приложении.

Рисунок 1. Уведомление со значком, заголовком и текстом.
Для получения более подробной информации о каждой части уведомления ознакомьтесь с разделом «Анатомия уведомления» .
Объявите разрешение во время выполнения.
Android 13 (уровень API 33) и выше поддерживают разрешение во время выполнения для отправки уведомлений, не подпадающих под исключения (включая уведомления от служб переднего плана (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)
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 (уровень 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...")
<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);
Для получения дополнительной информации о других стилях больших уведомлений, включая добавление изображения и элементов управления воспроизведением мультимедиа, см. раздел «Создание расширяемого уведомления» .
Создайте канал и установите уровень важности.
Прежде чем отправлять уведомления на 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)
}
}
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);
}
}
Поскольку в Android 8.0 и более поздних версиях необходимо создать канал уведомлений перед отправкой каких-либо уведомлений, выполните этот код сразу после запуска приложения. Вызов этого кода можно безопасно повторять, так как создание существующего канала уведомлений не выполняет никаких действий.
Конструктор NotificationChannel требует указания importance , используя одну из констант класса NotificationManager . Этот параметр определяет, как прерывать пользователя при получении любого уведомления, относящегося к этому каналу. Установите приоритет с помощью setPriority() для поддержки Android 7.1 и более ранних версий, как показано в предыдущем примере.
Хотя вам необходимо установить важность или приоритет уведомлений, как показано в следующем примере, система не гарантирует корректного поведения оповещений. В некоторых случаях система может изменять уровень важности в зависимости от других факторов, и пользователь всегда может переопределить уровень важности для данного канала.
Для получения более подробной информации о значении различных уровней ознакомьтесь с информацией об уровнях важности уведомлений .
Настройте действие нажатия для уведомления.
Каждое уведомление должно реагировать на касание, обычно для открытия активности в вашем приложении, соответствующей уведомлению. Для этого укажите намерение содержимого, определенное с помощью объекта PendingIntent , и передайте его в setContentIntent() .
Следующий фрагмент кода показывает, как создать базовое намерение для открытия активности при нажатии пользователем на уведомление:
Котлин
// Create an explicit intent for an Activity in your app.
<b>val intent = Intent(this, AlertDetails::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}</b>
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val builder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that fires when the user taps the notification.
<b>.setContentIntent(pendingIntent)</b>
.setAutoCancel(true)
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() , который автоматически удаляет уведомление, когда пользователь нажимает на него.
В приведенном выше примере флаги намерений сохраняют ожидаемый пользователем интерфейс навигации после открытия приложения с помощью уведомления. Вы можете использовать их в зависимости от типа запускаемого действия, которое может быть одним из следующих:
Активность, существующая исключительно для ответов на уведомление. Пользователь не должен переходить к этой активности во время обычного использования приложения, поэтому активность запускает новую задачу, а не добавляется к существующей задаче приложения и стеку возврата . Это тот тип намерения, который был создан в предыдущем примере.
Активность, которая является частью стандартного рабочего процесса вашего приложения. В данном случае запуск активности создает стек возврата, чтобы сохранить ожидания пользователя относительно кнопок «Назад» и «Вверх» .
Более подробную информацию о различных способах настройки намерения уведомления см. в разделе «Запуск действия из уведомления» .
Показать уведомление
Чтобы отобразить уведомление, вызовите метод 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())
}
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 и выше включите уведомления вручную или создайте диалоговое окно для запроса уведомлений.
Добавить кнопки действий
Уведомление может содержать до трех кнопок действий, позволяющих пользователю быстро отреагировать, например, отложить напоминание или ответить на текстовое сообщение. Однако эти кнопки действий не должны дублировать действие, выполняемое при нажатии пользователем на уведомление .

Рисунок 3. Уведомление с одной кнопкой действия.
Чтобы добавить кнопку действия, передайте PendingIntent в метод addAction() . Это похоже на настройку действия по умолчанию для нажатия уведомления, за исключением того, что вместо запуска активности вы можете сделать другие вещи, например, запустить BroadcastReceiver , который будет выполнять задачу в фоновом режиме, чтобы действие не прерывало работу уже открытого приложения.
Например, следующий код показывает, как отправить широковещательное сообщение конкретному получателю:
Котлин
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 .
Если же вы пытаетесь создать уведомление с кнопками воспроизведения мультимедиа, например, для паузы и пропуска треков, см. раздел о создании уведомления с элементами управления воспроизведением мультимедиа .
Добавить действие прямого ответа
Функция прямого ответа, представленная в Android 7.0 (уровень API 24), позволяет пользователям вводить текст непосредственно в уведомление. Затем текст доставляется в ваше приложение без открытия отдельной активности. Например, вы можете использовать функцию прямого ответа, чтобы позволить пользователям отвечать на текстовые сообщения или обновлять списки задач прямо из уведомления.

Рисунок 4. Нажатие кнопки «Ответить» открывает текстовое поле.
Действие прямого ответа отображается в виде дополнительной кнопки в уведомлении, которая открывает текстовое поле ввода. Когда пользователь заканчивает ввод текста, система прикрепляет текстовый ответ к указанному вами намерению для действия уведомления и отправляет это намерение в ваше приложение.
Добавьте кнопку ответа
Чтобы создать действие уведомления, поддерживающее прямой ответ, выполните следующие действия:
- Создайте экземпляр класса
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(); ``` - Создайте
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); ``` - Прикрепите объект
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(); ``` - Примените действие к уведомлению и отправьте уведомление. * {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;
}
После обработки текста обновите уведомление, вызвав метод 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)
}
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() получателя.
Добавьте ответ в конец уведомления, вызвав метод 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)
<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() .
Следует помнить, что пользователь всегда имеет полный контроль над тем, будут ли его уведомления отображаться на экране блокировки, и может управлять ими в зависимости от каналов уведомлений вашего приложения.
Обновить уведомление
Чтобы обновить уведомление после его отправки, снова вызовите метод NotificationManagerCompat.notify() , передав ему тот же идентификатор, который вы использовали ранее. Если предыдущее уведомление будет закрыто, вместо него будет создано новое.
При желании вы можете вызвать метод setOnlyAlertOnce() , чтобы уведомление прерывало пользователя — звуком, вибрацией или визуальными подсказками — только при первом появлении уведомления, а не при последующих обновлениях.
Удалить уведомление
Уведомления остаются видимыми до тех пор, пока не произойдет одно из следующих событий:
- Пользователь отклоняет уведомление.
- Пользователь нажимает на уведомление, если вы вызываете
setAutoCancel()при его создании. - Вызов метода
cancel()предназначен для конкретного идентификатора уведомления. Этот метод также удаляет текущие уведомления. - Вы вызываете
cancelAll(), который удаляет все ранее отправленные вами уведомления. - Если вы установили тайм-аут при создании уведомления с помощью
setTimeoutAfter(), указанная продолжительность истекает. При необходимости вы можете отменить уведомление до истечения указанного времени ожидания.
Рекомендации по использованию мессенджеров
При создании уведомлений для ваших приложений для обмена сообщениями и чата учитывайте приведенные здесь рекомендации.
Используйте MessagingStyle
Начиная с 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()
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/*.
Используйте прямой ответ
Функция «Прямой ответ» позволяет пользователю ответить на сообщение непосредственно в тексте.
- После того, как пользователь ответит, используя действие «Ответить прямо в тексте», используйте
MessagingStyle.addMessage()для обновления уведомленияMessagingStyleи не отменяйте и не удаляйте уведомление. Если уведомление не будет отменено, пользователь сможет отправить несколько ответов из этого уведомления. - Чтобы обеспечить совместимость действия «Встроенный ответ» с 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), чтобы переопределить режим «Не беспокоить».