lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Уведомления

Уведомление ― это сообщение, которое может быть выведено на экран за пределами обычного пользовательского интерфейса приложения. Когда вы сообщаете системе о необходимости выдать уведомление, оно сначала отображается в виде значка в области уведомлений. Чтобы просмотреть подробные сведения об уведомлении, пользователь открывает панель уведомлений. И областью уведомлений, и панелью уведомлений управляет система, а пользователь может их просматривать в любое время.

Рисунок 1. Уведомления в области уведомлений.

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

Примечание. Если не указано иное, в этом руководстве речь идет о классе NotificationCompat.Builder в версии 4 вспомогательной библиотеки. КлассNotification.Builder был добавлен в Android 3.0 (уровень API 11).

Рекомендации по разработке

Поскольку уведомления являются как важной составной частью пользовательского интерфейса Android, для них имеются собственные инструкции по проектированию. Появившиеся в Android 5.0 (уровень API 21) значительные изменения дизайна имеют особо важное значение, поэтому для получения более подробной информации вам следует ознакомиться с учебником по интерфейсу Material Design . Чтобы узнать, как проектировать уведомления и взаимодействие с ними, прочитайте руководство по проектированию Уведомления.

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

Информация о пользовательском интерфейсе и действия для уведомления указываются в объекте NotificationCompat.Builder. Чтобы создать само уведомление, вызывается метод NotificationCompat.Builder.build(), который возвращает объект Notification, содержащий заданные вами спецификации. Чтобы выдать уведомление, объект Notification передается в систему путем вызова метода NotificationManager.notify().

Обязательное содержимое уведомления

Объект Notification должен содержать следующие элементы:

  • небольшой значок, заданный с помощью setSmallIcon();
  • заголовок, заданный с помощью setContentTitle();
  • подробный текст, заданный с помощью setContentText().

Необязательные содержимое и настройки уведомления

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

Действия уведомлений

Несмотря на то что действия не являются обязательными, в уведомление необходимо добавить хотя бы одно из них. Действие позволяет пользователю перейти из уведомления прямо к операции Activity из вашего приложения, где они могут просмотреть одно или несколько событий либо выполнить какую-либо другую работу.

Уведомление может предоставлять возможность выполнить несколько действий. Следует всегда определять действие, которое вызывается, когда пользователь нажимает уведомление; обычно это действие открывает операцию Activity из вашего приложения. В уведомление также можно добавлять кнопки, которые выполняют дополнительные действия, например отключение сигнала будильника или немедленный ответ на текстовое сообщение; эта функция поддерживается начиная с версии Android 4.1. Если используются дополнительные кнопки действий, то также необходимо сделать их функции доступными в операции Activity из вашего приложения (подробные сведения см. в разделе Вопросы совместимости).

Внутри класса Notification само действие определяется объектом PendingIntent, содержащим объект Intent, который запускает операцию Activity из вашего приложения. Чтобы связать объект PendingIntent с жестом, вызовите соответствующий метод NotificationCompat.Builder. Например, если вам требуется запустить операцию Activity, когда пользователь нажимает текст уведомления в панели уведомлений, вы добавляете объект PendingIntent путем вызова метода setContentIntent().

Запуск операции Activity, когда пользователь нажимает уведомление, является наиболее распространенным вариантом действия. Операцию Activity также можно запускать, когда пользователь закрывает уведомление. В версии Android 4.1 или более поздних версиях запускать операцию Activity можно с помощью кнопки действия. Подробные сведения см. в справочном руководстве по классу NotificationCompat.Builder.

Приоритет уведомлений

При желании уведомлению можно задать приоритет. Приоритет действует как подсказка пользовательскому интерфейсу устройства о том, каким образом следует выводить уведомление. Чтобы задать приоритет уведомления, вызовите метод NotificationCompat.Builder.setPriority() и передайте ему одну из констант приоритетов NotificationCompat. Имеется пять уровней приоритета, начиная от PRIORITY_MIN (-2) и до PRIORITY_MAX (2). Если приоритет не задан, то по умолчанию он будет иметь значение PRIORITY_DEFAULT (0).

Сведения о присвоении подходящего уровня приоритета см. в разделе "Правильная настройка приоритета уведомления и управление им" в руководстве "Разработка уведомлений" .

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

Следующий фрагмент кода иллюстрирует простое уведомление, указывающее операцию, которую нужно будет открыть, когда пользователь нажмет уведомление. Обратите внимание, что этот код создает объект TaskStackBuilder и использует его для создания объекта PendingIntent для действия. Более подробно этот шаблон описан в разделе "Сохранение навигации при запуске операции":

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
        );
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());

Готово. Теперь пользователь получит уведомление.

Применение расширенного макета к уведомлению

Чтобы уведомление отображалось в расширенном виде, сначала создайте объект NotificationCompat.Builder с требуемыми параметрами обычного представления. Затем вызовите метод Builder.setStyle(), первым аргументом которого должен быть объект расширенного макета.

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

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

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("Event tracker")
    .setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
        new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Event tracker details:");
...
// Moves events into the expanded layout
for (int i=0; i < events.length; i++) {

    inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
mBuilder.setStyle(inBoxStyle);
...
// Issue the notification here.

Вопросы совместимости

Не все функции уведомлений поддерживаются в той или иной версии платформы, даже несмотря на то, что методы для их задания имеются в классе вспомогательной библиотеки NotificationCompat.Builder. Например, кнопки действий, которые зависят от расширенных уведомлений, отображаются только в версии Android 4.1 и последующих версиях, поскольку сами расширенные уведомления поддерживаются только начиная с версии Android 4.1.

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

  1. Предоставляйте все функции уведомления всем пользователям независимо от используемой ими версии. Для этого убедитесь, что все функции вызываются из операции Activity в вашем приложении. Возможно, для этого вам потребуется добавить новый объект Activity.

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

  2. Обеспечьте доступ к этой функции операции Activity всех пользователей, сделав так, чтобы эта операция запускалась, когда пользователь нажимает уведомление. Для этого создайте объект PendingIntent для операции Activity. Вызовите setContentIntent(), чтобы добавить объект PendingIntent в уведомление.
  3. Затем добавьте в свое уведомление требуемые функции расширенного уведомления. Помните, что любая добавляемая функция должна быть предусмотрена в операции Activity, которая запускается, когда пользователь нажимает уведомление.

Управление уведомлениями

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

Например, Gmail уведомляет пользователя о поступлении новых сообщений электронной почты путем увеличения счетчика непрочитанных сообщений и добавления в уведомления кратких сведений о каждом из них. Это называется "укладкой уведомлений в стопку" (stacking) и подробно описано в руководстве "Разработка уведомлений".

Примечание. Для этой функции Gmail требуется расширенный макет папки входящих сообщений, который входит в состав функции расширенных уведомлений, поддержка которой предусмотрена начиная с версии Android 4.1.

В разделах ниже описано, как обновлять уведомления, а также как удалять их.

Обновление уведомлений

Чтобы настроить уведомление таким образом, что его впоследствии можно было обновлять, его следует выдавать с идентификатором уведомления путем вызова метода NotificationManager.notify(). Чтобы изменить это уведомление, после того как оно выдано, обновите или создайте объект NotificationCompat.Builder, постройте на его основе объект Notification и выдайте объект Notification с тем же идентификатором, который использовался ранее. Если предыдущее уведомление все еще отображается на экране, система обновит его с использованием содержимого объектаNotification. Если предыдущее уведомление было закрыто, то вместо него будет создано новое уведомление.

Следующий фрагмент кода демонстрирует уведомление, которое обновляется с учетом количества произошедших событий. Он накладывает уведомления друг на друга (укладывает в стопку), отображая сводную информацию:

mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
    .setContentTitle("New Message")
    .setContentText("You've received new messages.")
    .setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
    mNotifyBuilder.setContentText(currentText)
        .setNumber(++numMessages);
    // Because the ID remains unchanged, the existing notification is
    // updated.
    mNotificationManager.notify(
            notifyID,
            mNotifyBuilder.build());
...

Удаление уведомлений

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

  • пользователь закроет уведомления по одному или командой "Очистить все" (если уведомление можно очистить);
  • пользователь нажмет уведомление, а вы вызвали метод setAutoCancel(), когда создавали уведомление;
  • вы вызовете метод cancel() для уведомления с определенным идентификатором. Кроме того, этот метод удаляет текущие уведомления;
  • вы вызовете метод cancelAll(), который удаляет все ранее выданные вами уведомления.

Сохранение навигации при запуске операции

Когда вы запускаете операцию Activity из уведомления, вам необходимо сохранить привычные пользователю приемы навигации. При нажатии "Назад" пользователь должен возвращаться назад в обычном потоке операций приложения вплоть до главного экрана, а при нажатии "Последние" операция Activity должна быть отображена как отдельная задача. Чтобы сохранить приемы навигации, операцию Activity следует запускать в новой задаче. Как настроить объект PendingIntent таким образом, чтобы получить новую задачу, зависит от типа операции Activity, которую вы запускаете. В целом есть две ситуации:

Обычная операция
Вы запускаете операцию Activity, которая является частью обычного потока работы приложения. В этом случае настройте объект PendingIntent на запуск новой задачи и предоставьте объекту PendingIntent стек переходов назад, который воспроизводит обычную работу приложения в ситуации, когда пользователь нажимает "Назад" .

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

Происходит это независимо от того, в каком приложении вы находились в тот момент, когда нажали уведомление. Например, если при составлении сообщения в Gmail вы нажмете уведомление об одном сообщении электронной почты, вы сразу же перейдете в это сообщение. При нажатии "Назад" вы перейдете в папку входящих сообщений, а затем на главный экран, а не в сообщение, которое составляли.

Особая операция
Пользователь может увидеть эту операцию Activity, только если она запущена из уведомления. В некотором смысле операция Activity расширяет уведомление путем предоставления информации, которую было бы сложно отобразить в самом уведомлении. В этом случае настройте объект PendingIntent на запуск в новой задаче. При этом создавать стек переходов назад не требуется, поскольку запущенная операция Activity не является частью потока операций приложения. При нажатии "Назад" пользователь все же перейдет на главный экран.

Настройка PendingIntent обычной операции

Чтобы настроить объект PendingIntent, который непосредственно запускает операцию Activity, выполните следующие шаги:

  1. Определите иерархию операций Activity своего приложения в файле манифеста.
    1. Добавьте поддержку для версии Android 4.0.3 и более ранних версий. Для этого укажите родительский объект операции Activity, которую запускаете, добавив элемент <meta-data> в качестве дочернего для элемента <activity>.

      Для этого элемента задайте android:name="android.support.PARENT_ACTIVITY". Задайте android:value="<parent_activity_name>", где <parent_activity_name> ― это значение android:name для родительского элемента <activity> . В качестве примера см. следующий код XML.

    2. Также добавьте поддержку для версии Android 4.1 и более поздних версий. Для этого добавьте атрибут android:parentActivityName в элемент <activity> запускаемой операцииActivity.

    Итоговый код XML должен выглядеть следующим образом:

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ResultActivity"
        android:parentActivityName=".MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".MainActivity"/>
    </activity>
    
  2. Создайте стек переходов назад, основанный на объекте Intent, который запускает операцию Activity:
    1. Создайте объект Intent, который запускает операцию Activity.
    2. Создайте построитель стека, вызвав метод TaskStackBuilder.create().
    3. Добавьте стек переходов назад в построитель стеков путем вызова метода addParentStack(). Для каждой операции Activity из иерархии, определенной в файле манифеста, в стеке переходов назад имеется объект Intent, который запускает Activity. Этот метод также добавляет флаги, которые запускают стек в новой задаче.

      Примечание. Несмотря на то что аргумент addParentStack() является ссылкой на запускаемую операцию Activity, при вызове этого метода не добавляется объект Intent, который запускает операцию Activity. Это делается на следующем шаге.

    4. Добавьте объект Intent, который запускает операцию Activity из уведомления, путем вызова метода addNextIntent(). Передайте объект Intent, созданный вами на первом шаге, в качестве аргумента методу addNextIntent().
    5. При необходимости добавьте аргументы в объекты Intent из стека путем вызова метода TaskStackBuilder.editIntentAt(). Иногда это требуется для того, чтобы целевая операция Activity отображала значимые данные, когда пользователь переходит в нее с помощью действия "Назад".
    6. Получите объект PendingIntent для этого стека переходов назад путем вызова метода getPendingIntent(). Затем этот объект PendingIntent можно будет использовать в качестве аргумента для метода setContentIntent().

Следующий фрагмент кода демонстрирует этот процесс:

...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

Настройка PendingIntent особой операции

В приведенном далее разделе описывается настройка объекта PendingIntent для особой операции.

Особой операции Activity не требуется стек перехода назад, поэтому не нужно определять иерархию объектов Activity в файле манифеста и вызывать метод addParentStack() для построения стека перехода назад. Вместо этого в файле манифеста задайте параметры задачи Activity и создайте объект PendingIntent путем вызова метода getActivity():

  1. Добавьте следующие атрибуты в элемент <activity> в файле манифеста для операции Activity
    android:name="activityclass"
    Полное имя класса операции.
    android:taskAffinity=""
    В сочетании с флагом FLAG_ACTIVITY_NEW_TASK, который вы задали в коде, это гарантирует, что данная операция Activity не перейдет в задачу приложения, используемую по умолчанию. Любые существующие задачи, имеющие отношение к используемой по умолчанию задаче приложения, затронуты не будут.
    android:excludeFromRecents="true"
    Исключает новую задачу из списка "Последние",с тем чтобы пользователь не мог случайно вернуться в нее.

    Данный элемент показан в этом фрагменте кода:

    <activity
        android:name=".ResultActivity"
    ...
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    ...
    
  2. Построение и выдача уведомления:
    1. Создайте объект Intent, который запускает операцию Activity.
    2. Настройте операцию Activity, запускаемую в новой пустой задаче, путем вызова метода setFlags() с флагами FLAG_ACTIVITY_NEW_TASK и FLAG_ACTIVITY_CLEAR_TASK.
    3. Задайте для объекта Intent любые другие требуемые параметры.
    4. Создайте объект PendingIntent из объекта Intent путем вызова метода getActivity(). Затем этот объект PendingIntent можно будет использовать в качестве аргумента для метода setContentIntent().

    Следующий фрагмент кода демонстрирует этот процесс:

    // Instantiate a Builder object.
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    // Creates an Intent for the Activity
    Intent notifyIntent =
            new Intent(this, ResultActivity.class);
    // Sets the Activity to start in a new, empty task
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    // Creates the PendingIntent
    PendingIntent notifyPendingIntent =
            PendingIntent.getActivity(
            this,
            0,
            notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT
    );
    
    // Puts the PendingIntent into the notification builder
    builder.setContentIntent(notifyPendingIntent);
    // Notifications are issued by sending them to the
    // NotificationManager system service.
    NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // Builds an anonymous Notification object from the builder, and
    // passes it to the NotificationManager
    mNotificationManager.notify(id, builder.build());
    

Отображение хода выполнения в уведомлении

Уведомления могут содержать индикатор хода выполнения с эффектом анимации, который показывает пользователям состояние текущей операции. Если имеется возможность оценить, сколько времени занимает операция и какой процент ее объема уже завершен, используйте "определенную" форму индикатора (индикатор хода выполнения). Если продолжительность операции оценить невозможно, используйте "неопределенную" форму индикатора (индикатор операции).

Индикаторы хода выполнения отображаются с помощью реализации класса ProgressBar платформы.

Для использования индикатора хода выполнения на платформах начиная с Android 4.0 вызовите метод setProgress(). Для предыдущих версий необходимо будет создать собственный нестандартный макет уведомлений, который содержит представление ProgressBar.

В приведенных далее разделах описывается отображение хода выполнения в уведомлении с помощью setProgress().

Отображение индикатора хода выполнения фиксированной продолжительности

Чтобы вывести на экран определенный индикатор хода выполнения, добавьте его в свое уведомление, вызвав метод setProgress(max, progress, false), а затем выдайте уведомление. По мере выполнения увеличивайте значение progress и обновляйте уведомление. По окончании операции progress должен быть равен max. Стандартный способ вызова метода setProgress() заключается в следующем: задать значение max равным 100 с последующим увеличением progress в виде величины "процента выполнения" операции.

По окончании операции можно оставить этот индикатор хода выполнения на экране или удалить его. В любом случае не забывайте обновить текст уведомления, чтобы указать, что операция выполнена. Чтобы удалить индикатор выполнения, вызовите метод setProgress(0, 0, false). Например:

...
mNotifyManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
    .setContentText("Download in progress")
    .setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
    new Runnable() {
        @Override
        public void run() {
            int incr;
            // Do the "lengthy" operation 20 times
            for (incr = 0; incr <= 100; incr+=5) {
                    // Sets the progress indicator to a max value, the
                    // current completion percentage, and "determinate"
                    // state
                    mBuilder.setProgress(100, incr, false);
                    // Displays the progress bar for the first time.
                    mNotifyManager.notify(0, mBuilder.build());
                        // Sleeps the thread, simulating an operation
                        // that takes time
                        try {
                            // Sleep for 5 seconds
                            Thread.sleep(5*1000);
                        } catch (InterruptedException e) {
                            Log.d(TAG, "sleep failure");
                        }
            }
            // When the loop is finished, updates the notification
            mBuilder.setContentText("Download complete")
            // Removes the progress bar
                    .setProgress(0,0,false);
            mNotifyManager.notify(ID, mBuilder.build());
        }
    }
// Starts the thread by calling the run() method in its Runnable
).start();

Отображение непрерывного индикатора операции

Для отображения неопределенного индикатора операции добавьте его в свое уведомление с помощью метода setProgress(0, 0, true) (два первых аргумента игнорируются) и выдайте уведомление. В результате будет показан индикатор, который будет иметь такой же стиль, что и индикатор хода выполнения, за исключением того, что его анимация будет непрерывной.

Выдайте уведомление в начале операции. Анимация будет воспроизводиться до тех пор, пока вы не измените уведомление. Когда операция будет выполнена, вызовите метод setProgress(0, 0, false), после чего обновите уведомление, удалив индикатор операции. Всегда поступайте таким образом. В противном случае анимация будет воспроизводиться и после завершения операции. Также не забывайте изменить текст уведомления, чтобы указать, что операция выполнена.

Чтобы посмотреть, как работают индикаторы операций, перейдите к предыдущему фрагменту кода. Найдите следующие строки:

// Sets the progress indicator to a max value, the current completion
// percentage, and "determinate" state
mBuilder.setProgress(100, incr, false);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

Замените их вот этими строками:

 // Sets an activity indicator for an operation of indeterminate length
mBuilder.setProgress(0, 0, true);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

Метаданные уведомления

Уведомления можно сортировать в соответствии с метаданными, которые назначаются с помощью следующих методов NotificationCompat.Builder:

  • метод setCategory() информирует систему о том, как обрабатывать уведомления вашего приложения, когда устройство находится в режиме приоритета (например, если ваше уведомление сообщает о входящем вызове, мгновенном сообщении или сигнале будильника);
  • методsetPriority() вызывает отображение уведомлений, в поле приоритета которых задано значение PRIORITY_MAX или PRIORITY_HIGH , в небольшом плавающем окне, если уведомление также сопровождается звуковым сигналом или вибрацией;
  • метод addPerson() позволяет добавить к уведомлению список людей. С его помощью ваше уведомление может сигнализировать системе о том, что она должна сгруппировать уведомления от указанных людей или считать уведомления от этих людей более важными.

Рисунок 3. Полноэкранная операция, отображающая уведомление heads-up

Уведомления heads-up

В Android 5.0 (уровень API 21) уведомления могут отображаться в небольшом плавающем окне (оно также называется уведомлением heads-up), когда устройство активно (то есть устройство разблокировано и его экран включен). Эти уведомления выглядят так же, как компактная форма вашего уведомления, за исключением того, что в уведомлениях heads-up также отображаются кнопки действий. Пользователи могут выполнять действия или закрывать уведомление heads-up, не покидая текущее приложение.

Примеры ситуаций, в которых могут быть вызваны уведомления heads-up:

  • операция пользователя выполняется в полноэкранном режиме (приложение использует fullScreenIntent) или;
  • уведомление имеет высокий приоритет и использует рингтоны или вибрацию.

Уведомления на экране блокировки

С выходом версии Android 5.0 (уровень API 21) уведомления теперь могут отображаться на экране блокировки. С помощью этой функции можно выводит на экран элементы управления мультимедиа и другие стандартные действия. В настройках пользователи могут выбрать, следует ли отображать уведомления на экране блокировки, а вы можете указать, будет ли уведомление из вашего приложения видно на нем.

Настройка видимости

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

  • VISIBILITY_PUBLIC показывает полное содержимое уведомления;
  • VISIBILITY_SECRET не отображает какую-либо часть этого уведомления на экране блокировки;
  • VISIBILITY_PRIVATE показывает базовую информацию, такую как значок уведомления и заголовок его содержимого, но скрывает полное содержимое уведомления.

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

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

В версии Android 5.0 (API уровня 21) на экране блокировки больше не отображаются элементы управления воспроизведением мультимедиа, основанные на классе RemoteControlClient, использование которого прекращено. Вместо этого используйте шаблон Notification.MediaStyle с методом addAction() , который преобразует действия в доступные для нажатия значки.

Примечание. Шаблон и метод addAction() не входят в состав вспомогательной библиотеки, поэтому эти функции работают только в версии Android 5.0 и последующих версиях.

Чтобы отобразить элементы управления мультимедиа на экране блокировки в Android 5.0, задайте для видимости значение VISIBILITY_PUBLIC, выполнив описанную выше процедуру. Затем добавьте действия и задайте шаблон Notification.MediaStyle, как описано в следующем образце кода:

Notification notification = new Notification.Builder(context)
    // Show controls on lock screen even when user hides sensitive content.
    .setVisibility(Notification.VISIBILITY_PUBLIC)
    .setSmallIcon(R.drawable.ic_stat_player)
    // Add media control buttons that invoke intents in your media service
    .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
    .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)  // #1
    .addAction(R.drawable.ic_next, "Next", nextPendingIntent)     // #2
    // Apply the media style template
    .setStyle(new Notification.MediaStyle()
    .setShowActionsInCompactView(1 /* #1: pause button */)
    .setMediaSession(mMediaSession.getSessionToken())
    .setContentTitle("Wonderful music")
    .setContentText("My Awesome Band")
    .setLargeIcon(albumArtBitmap)
    .build();

Примечание. Прекращение использования класса RemoteControlClient имеет и другие последствия для управления мультимедиа. Подробные сведения о новых API-интерфейсах для управления сеансами воспроизведения мультимедиа см. в разделе Управление воспроизведением мультимедиа .

Нестандартные макеты уведомлений

Платформа уведомлений позволяет задавать нестандартные макеты уведомлений, которые определяют внешний вид уведомлений в объекте RemoteViews. Уведомления с нестандартным макетом — такие же, как обычные уведомления, но в их основе лежит класс RemoteViews, определенный в файле XML макета.

Высота изображения, которую можно получить с использованием нестандартного макета уведомления, зависит от представления уведомления. Обычные макеты представления ограничены по высоте 64 пикселами, а расширенные — 256 пикселами.

Чтобы определить нестандартный макет уведомления, начните с инициализации объекта RemoteViews, который загружает файл XML макета. Затем, вместо вызова методов, например setContentTitle(), вызовите setContent(). Чтобы задать сведения о содержимом в нестандартном уведомлении, используйте методы из RemoteViews, чтобы определить значения для дочерних представлений:

  1. Создайте макет XML для уведомления в отдельном файле. Можно использовать любое имя файла по своему усмотрению, однако расширение должно быть .xml
  2. В своем приложении с помощью методов RemoteViews определите значки и текст уведомления. Поместите этот объект RemoteViews в свой NotificationCompat.Builder, вызвав метод setContent(). Не следует задавать фон Drawable для объекта RemoteViews, поскольку цвет текста может стать нечитаемым.

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

Внимание! При использовании нестандартного макета уведомлений следует особое внимание уделять обеспечению совместимости такого макета с разными вариантами ориентации устройства и разрешения экрана. Этот совет относится ко всем макетам View, но особенно важен он для уведомлений, поскольку размер панели уведомлений весьма ограничен. Не следует делать свои нестандартные макеты слишком сложными и обязательно нужно тестировать их на различных конфигурациях устройств.

Использование ресурсов стиля для текста нестандартного уведомления

Для форматирования текста нестандартного уведомления всегда используйте ресурсы стиля. Цвет фона уведомления может меняться на разных устройствах и в разных версиях системы, а использование ресурсов стиля позволяет это учесть. Начиная с версии Android 2.3 система определяет стиль для текста уведомления со стандартным макетом. Если вы используете тот же стиль в приложениях, предназначенных для версии Android 2.3 и последующих версий, то вы гарантируете видимость своего текста на фоне экрана.