Как сгруппировать уведомления в Android, чтобы они не показывались отдельно
Androidгруппировкаоперационные системыразработка под Androidуведомления
Что проверяют
Знание модели уведомлений: канал, ключ группы, сводное уведомление и поведение алертов. Хороший ответ отличает группу уведомлений от группы каналов и помнит, что без сводки на старых версиях группировка не включится.
Как отвечать
Группировка строится на трёх вещах: одинаковый setGroup(ключ) у всех дочерних уведомлений, отдельное уведомление со setGroupSummary(true) и тем же ключом, и общий канал.
private const val CHANNEL_ID = "messages"
private const val GROUP_KEY = "com.example.MESSAGES"
private const val SUMMARY_ID = 0
// канал обязателен начиная с Android 8.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID, "Сообщения", NotificationManager.IMPORTANCE_DEFAULT
)
getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
}
val child = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("Анна")
.setContentText("Привет")
.setGroup(GROUP_KEY)
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
.build()
val summary = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_message)
.setStyle(
NotificationCompat.InboxStyle()
.addLine("Анна: Привет")
.addLine("Игорь: Созвон в 15:00")
.setSummaryText("3 новых сообщения")
)
.setGroup(GROUP_KEY)
.setGroupSummary(true)
.build()
with(NotificationManagerCompat.from(this)) {
notify(messageId, child) // уникальный id на каждое сообщение
notify(SUMMARY_ID, summary) // постоянный id сводки
}Что нужно проговорить отдельно:
setGroupAlertBehaviorи есть ответ на «чтобы не показывались отдельно». Без него звук и вибрация сработают на каждое дочернее уведомление.GROUP_ALERT_SUMMARYоставляет алерт только сводке,GROUP_ALERT_CHILDRENнаоборот глушит сводку.- Начиная с Android 7.0 система сама собирает уведомления приложения в пачку, если их четыре и больше, и генерирует сводку из их текста. Своя сводка нужна, чтобы контролировать её вид и чтобы группировка работала на более старых версиях, а также когда уведомлений меньше четырёх.
- Уникальные id у дочерних. Один и тот же id перезапишет предыдущее уведомление, и группировать станет нечего. Сводке наоборот нужен постоянный id, чтобы она обновлялась, а не плодилась.
- Android 13 (API 33) требует runtime-разрешение
POST_NOTIFICATIONS. Без негоnotifyтихо ничего не делает, и это самая частая причина «код правильный, но ничего не показывается». - Отмена. Когда снято последнее дочернее уведомление, сводка на части версий остаётся висеть. Надёжно: считать оставшиеся через
NotificationManager.getActiveNotifications()и явно снимать сводку, если детей не осталось. - Для мессенджеров вместо
InboxStyleлучшеMessagingStyle: система сама рисует переписку, поддерживает аватары и inline-ответ. - Не путать с
NotificationChannelGroup: она объединяет каналы в настройках приложения и на вид уведомлений в шторке не влияет.
Где спотыкаются
Ставят setGroup всем уведомлениям, но не создают сводку, и на старых версиях ничего не сворачивается. Второй провал: забывают setGroupAlertBehavior, и пачка из десяти сообщений устраивает десять звуков подряд.