Создавая кнопки в уведомлении нельзя просто назначить им слушатели, как мы привыкли делать редактируя интерфейс пользователя. Основным способом назначения действий в уведомлении являются интенты (Intent) — намерения.

И если для того, чтобы назначить кнопке действия перехода в какую-либо Activity достаточно просто создать соответствующий интент, внутри которого и будет описано необходимое действие, а именно — откуда и куда переходим, то в нашем случае необходимо будет сделать следующее: назначить кнопке намерение, передать ему Action для работы с интент фильтром, создать BroadcastReciver, который будет вылавливать наш Intent и уже тогда выполнять необходимый нам метод.

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

//Создаем уникальный ключ
String BROADCAST_ACTION = "com.example.uniqueTag";

public void sendNotification () {
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        Intent intent = new Intent(BROADCAST_ACTION);
        //В следующей строке мы определяем кто именно будет обрабатывать наш Intent с помощью .getBroadcast
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intentStopTrip, 0);
        //Создаем уведомление
        Notification BuilderNote =
                new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.ic_example)
                        .setContentTitle("Example title")
                        .setContentText("Example text")
                        .setContentIntent(pendingIntentPush)
                        //Далее мы создадим кнопку и присвоим ей наш pendingIntent
                        .addAction(R.mipmap.ic_example, "Button name", pendingIntent)
                        .build();
        //Установим необходимые флаги
        BuilderNote.flags |= Notification.FLAG_AUTO_CANCEL;

        notificationManager.notify(0, BuilderNote);
    }

Теперь необходимо создать приемник BroadCastReciver. Для этого необходимо щелкнуть ПКМ по вашей папке app->New->Other->BroadcastReciver. Далее дайте ему имя, и в открывшемся файле нам необходимо убрать заглушку в виде вброса исключения, написав на ее месте наш метод

public class ExampleReciver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        exampleMethod();
    }
}

Но помимо этого нам необходимо настроить Intent Filter для нашего приемника, чтобы дать ему понять, какие именно Inetnt ему надо принимать. Для этого заходим в манифест и блоке кода нашего приемника прописываем Intent Filter, куда записываем содержимое строковой переменной BROADCAST_ACTION созданной в самом начале

<receiver
            android:name=".StopTimerReciver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.uniqueTag" />
            </intent-filter>
        </receiver>

Вот и все, теперь в случае нажатия на созданную нами кнопку в уведомлении будет запускаться метод, определенный в теле BroadcastReciver

Комментарии (4)


  1. ulman95
    03.05.2018 18:02

    Спасибо, очень познавательно!
    Жду теперь статью о том, как установить текст в TextView.


    1. Pyure Автор
      03.05.2018 18:05

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


    1. vikarti
      04.05.2018 11:01

      Там тоже… возможны особенности, например:
      — что если надо часть текста другим цветом? (Span'ы использовать)
      — что если у нас TextView над картинкой, текст приходит с сервера и надо переносы делать с учетом + в зависимости от текста — изменять эту самую картинку (убрать вообще TextView и рисовать свой контрол)


  1. anegin
    03.05.2018 18:08

    Начиная с Android Oreo не будут работать Broadcast Receiver'ы, статически добавленные через манифест, и которые вызываются неявно (без указания класса, а только по action).
    Нужно или динамически регистрировать BroadcastReceiver в запущенном приложении (в активити или foreground-сервисе), или запускать активити/сервис через PendingIntent.getActivity(), PendingIntent.getService()