В Android Oreo (API 26) появилась возможность создавать каналы для уведомлений. В этом уроке разберемся, как это делать и зачем это нужно.
Для каждого приложения пользователь может настроить уведомления. Для этого надо зайти в настройки системы, там выбрать Apps, найти в списке и открыть нужное приложение и выбрать раздел Notifications.
По умолчанию настройки выглядят так:
Настроек немного, и они затронут все уведомления от данного приложения.
Каналы позволяют расширить эти настройки и применять их выборочно. Разработчик приложения создает канал и указывает его ID при создании уведомлений. Пользователь в системных настройках приложения видит этот канал и может настроить его: важность, звук, вибру и пр. В итоге все уведомления, которые принадлежат этому каналу, будут отображаться с этими настройками.
Т.е. создавая канал, разработчик дает пользователю возможность настроить поведение определенной группы уведомлений.
Давайте создадим канал:
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "My channel", NotificationManager.IMPORTANCE_HIGH); channel.setDescription("My channel description"); channel.enableLights(true); channel.setLightColor(Color.RED); channel.enableVibration(false); notificationManager.createNotificationChannel(channel); }
Каналы актуальны только для Android Oreo и выше, поэтому используется проверка версии Android. Далее я не буду включать эту проверку в примеры, чтобы не загромождать код.
В конструкторе NotificationChannel указываем ID, имя и важность. Далее указываем прочие данные и настройки. По названию методов все понятно.
Методом createNotificationChannel создаем канал.
Теперь Notifications настройки приложения выглядят так:
Появились два канала: дефолтный и наш созданный My channel. Настройки дефолтного будут использованы для уведомлений, для которых не был указан канал.
Откроем настройки My channel:
Обратите внимание, что пункт Vibrate выключен. Мы явно указали это при создании канала, используя метод enableVibration(false).
Теперь при создании уведомлений вы можете указать ID канала, и уведомления будут отображены в соответствии с настройками этого канала.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("Title") .setContentText("Notification text");
ID канала указывается в конструкторе билдера уведомления. И теперь этот конструктор не будет зачеркнут как Deprecated, если вы используете библиотеку appCompat версии 26 и выше.
В какой момент создавать канал? Можно при старте приложения. Даже если канал уже был ранее создан, то просто ничего не произойдет. Но судя по тому, что пользователь не может удалять каналы, я думаю, можно использовать какой-нить флаг, который мы установим в true после первого создания каналов, и в дальнейшем он будет говорить нам о том, что каналы уже созданы.
Группа
Рассмотрим пример почтового приложения. Предположим, что оно умеет работать не только с почтой, но и с календарем. Т.е. оно может нам присылать уведомления двух типов: письма и события.
Соответственно, мы можем создать два канала - один для уведомлений о письмах, другой - для событий. В результате, пользователь сам сможет настроить под себя отдельно уведомления о письмах и отдельно о событиях. Это удобно.
Но наше приложение поддерживает несколько учетных записей. И под каждую учетную запись нам необходимо создавать два канала для уведомлений.
При создании 4-х каналов настройки будут выглядеть так:
Можно это улучшить, используя группы. Группа - это просто способ визуально разделить каналы в настройках.
Создается группа так:
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannelGroup( new NotificationChannelGroup(GROUP_ID, "Group 1"));
В конструкторе указываем ID и имя.
Далее, при создании канала используем метод setGroup, чтобы указать какой группе будет принадлежать канал.
NotificationChannel channel = new NotificationChannel(...); // ... channel.setGroup(GROUP_ID); notificationManager.createNotificationChannel(channel);
Таким образом для каждой учетной записи нашего приложения мы можем создать группу, и указать ее при создании каналов уведомлений этой учетной записи:
User A (group)
Mail (channel)
Events (channel)
User B (group)
Mail (channel)
Events (channel)
Теперь настройки выглядят лучше:
Каналы сгруппированы по учетным записям.
Получение информации о канале
В любой момент после создания канала, вы можете получить информацию о нем.
NotificationChannel channel = notificationManager.getNotificationChannel(CHANNEL_ID);
Метод getNotificationChannel вернет вам объект NotificationChannel или null, если канал с указанным ID не был найден. Используя различные get-методы канала, вы сможете узнать, как пользователь настроил ваш канал. Но вы не сможете перенастроить его, set-методы просто не будут работать.
Единственное, что вы можете поменять - это имя канала и его описание (description). Для этого необходимо просто пересоздать канал с новыми параметрами и тем же ID.
Если вы считали настройки канала и по каким-то причинам решили, что пользователь не прав, то вы можете попросить его поменять настройки.
Например, если пользователь выключил отображение уведомлений для канала, открываем настройки этого канала.
NotificationChannel channel = notificationManager.getNotificationChannel(CHANNEL_ID); if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) { Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.getId()); intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName()); startActivity(intent); }
Если getImportance равен IMPORTANCE_NONE, это значит, что канал был выключен пользователем. Создаем Intent с указанием ID канала и package приложения и запускаем Activity.
Разумеется, в реальном приложении надо действовать не так топорно, а сначала поинтересовать мнением пользователя и объяснить, почему вы хотите, чтобы он поменял настройки канала.
Удаление канала
Чтобы удалить канал, используйте метод deleteNotificationChannel
notificationManager.deleteNotificationChannel(CHANNEL_ID);
Технически вы конечно, можете использовать удаление, а затем создание канала, чтобы восстановить ваши настройки. Но так делать не рекомендуется. К тому же в настройках, в самом низу, пользователь будет видеть, сколько каналов было удалено.
И он поймет, что вы просто пересоздаете канал и сбрасываете его настройки.
Importance vs Priority
Если вы помните, при создании уведомления, мы можем в билдере указать приоритет. Начиная с Android Oreo приоритеты уведомлений были объявлены устаревшими и заменены параметром канала - важность.
Присоединяйтесь к нам в Telegram:
- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня