Android Notification Действие не запускается (PendingIntent) - программирование
Подтвердить что ты не робот

Android Notification Действие не запускается (PendingIntent)

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

Intent stopIntent = new Intent(this, MusicPlayerNew.class);
stopIntent.putExtra("STOP", "STOP");
PendingIntent stopPendingIntent = PendingIntent.getActivity(this, 0,
                stopIntent, PendingIntent.FLAG_UPDATE_CURRENT, null);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent);

Теперь в методе onResume() моей активности я проверяю с помощью getIntent(). getStringExtra() для опции "STOP" дополнительно, но намерение, которое я получил через getIntent(), не имеет дополнительных настроек: (

Я также попытался проверить, чтобы отправить широковещательную рассылку (у меня есть широковещательный приемник, работающий для связи от службы к активности)

Intent stopIntent2 = new Intent(MusicPlayerNew.STOP_MEDIAPLAYER);
PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
                stopIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent2); 

Теперь это работает, если в настоящее время активность находится на переднем плане. Если действие находится в фоновом режиме, кнопка остановки ничего не делает: (

EDIT: У меня есть BroadcastReceiver в моей деятельности как частный класс

private class DataUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
..
}}

В onResume() зарегистрируйте мое приложение для этого получателя:

intentFilter = new IntentFilter(STOP_MEDIAPLAYER);
registerReceiver(dataUpdateReceiver, intentFilter);

OnPause()

unregisterReceiver(dataUpdateReceiver);

Теперь, если я удаляю регистрацию из метода onPause(), широковещательная передача принимается, даже если приложение/действие больше не находится на переднем плане. Но правильно ли это сделать? Я получил этот материал для регистрации/отписки от учебника в Интернете, я думаю.

4b9b3361

Ответ 1

Я нашел решение в этом потоке в коде google https://code.google.com/p/android/issues/detail?id=61850

Чтобы исправить это, вы должны добавить флаг PendingIntent.FLAG_CANCEL_CURRENT в свой PendingIntent.

PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
            stopIntent2, PendingIntent.FLAG_CANCEL_CURRENT);

Ответ 2

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

  • Использование FLAG_CANCEL_CURRENT, как указано Nik.
  • Передача уникального requestCode в pendingIntent следующим образом

    PendingIntent pi = PendingIntent.getService(this, UNIQUE_ID, pi, 0);
    

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

Ответ 3

Сегодня я столкнулся с этой проблемой, и это было вызвано тем, что активность не была зарегистрирована или добавлена ​​в AndroidManifest.xml. Я думал, что я его там, но это не так. Кроме того, ошибки не регистрировались, пытаясь вызвать действие с его намерением.

Я понял это, создав намерение, а затем вызвал startAcitivty (намерение) без использования уведомления. Затем он дал мне сообщение о том, что в манифесте, вероятно, отсутствовала активность.

Если ни один из других ответов не решит вашу проблему, то, надеюсь, это будет. Обычно сложные проблемы - результат чего-то простого и глупого.

Ответ 4

Это очень поздний ответ, но он может помочь кому-то:

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

Для Действия используйте ниже:

Intent i = new Intent(this, YourActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

Для Сервис используйте ниже:

Intent i = new Intent(this, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);

Для широковещательного приемника используйте ниже:

Intent i = new Intent(this, YourReciver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);

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

Ответ 5

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

public final String ACTION_STOP = "yourpackagename.ACTION_STOP";

И затем создайте свои намерения следующим образом:

Intent stopIntent = new Intent(this, YourService.class).setAction(YourService.ACTION_STOP);
PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, 0);

Конечно, прекратите воспроизведение в своей сервисной функции startCommand, если действие намерения равно ACTION_STOP.

Это должно сделать трюк;)

Ответ 6

Вы не получаете широковещательную передачу, когда она находится в фоновом режиме, потому что вы не регистрируетесь в onPause. Переместите код unregisterReceiver в функцию onDestroy. Это будет вызвано только тогда, когда действие будет уничтожено. Или вы можете отменить регистрацию после того, как произошло ожидаемое событие.

Ответ 7

Здесь есть несколько вопросов:

Часть 1: Почему ваше намерение не получает дополнительный "STOP" ? Хотя это не видно в коде, который вы предоставили, я хотел бы подтвердить, используете ли вы флаг FLAG_ACTIVITY_SINGLE_TOP для намерения уведомления? Если это так, то намерение, которое вы получаете в своей деятельности, было бы намерением начать эту деятельность, и, следовательно, дополнительная опция "STOP" будет недоступна. Вам нужно будет расширить onNewIntent() в этом случае (где отправляется новое намерение). Дополнительная информация здесь.
Если вы не использовали FLAG_ACTIVITY_SINGLE_TOP, это означает, что при вводе уведомлений создается новое действие, и в этом случае Intent должен иметь параметр "STOP" . Если вы можете предоставить мне весь соответствующий код, я могу помочь вам лучше.

Часть 2: Использование широковещательного приемника Это не так прямо, как вы уже обнаружили. Вам нужно будет отменить регистрацию в onDestroy, и если ваша активность будет закрыта пользователем, может быть вызван onDestroy, и ваш широковещательный приемник может не активироваться во время уведомления пользователя пользователем. Если вы вообще не регистрируете регистрацию, это может показаться рабочим, но это утечка памяти, GC может очистить в любое время, что может привести к сбою в вашей программе, то есть вы ДОЛЖНЫ отменять регистрацию. Если вам нужно пойти с широковещательным приемником, вам нужно иметь сервис, чтобы сделать это, и сервис поставляется с собственными ловушками → перезапуск системы, разрядка аккумулятора и т.д. Я бы настоятельно рекомендовал вам перейти к первому подходу.

Ответ 8

У меня была очень похожая проблема, но это было совсем другое решение. Ожидающее намерение также не запускается, если вы объявили <service android:enabled="false"></service> в файле manifest.xml.

Заменить с android:enabled="false" на android:enabled="true"

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

Ответ 9

Для меня решением было установить флаги намерения:

resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_CLEAR_TASK);