Действие уведомления Android не запускается (PendingIntent)

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

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" extra, но намерение, которое я получил через 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); 

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

EDIT: У меня есть BroadcastReceiver в моей деятельности в качестве частного класс!--6-->

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 (), трансляция будет получена, даже если приложение/Активность больше не находится на переднем плане. Но правильно ли это? Я получил этот register / unregister-материал из учебника в Интернете, я думаю..

9 ответов


Я нахожу решение в этой теме на Google code 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);

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

  1. использование FLAG_CANCEL_CURRENT, как указано Ник.
  2. передача уникального requestCode до pendingIntent следующим образом

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

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


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

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

на активность использовать ниже:

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);

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


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

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

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


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

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.

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


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


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

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

Часть 2: Использование Широковещательного Приемника Это не прямолинейно, как вы уже поняли. Вы должны отменить регистрацию в onDestroy и если ваша деятельность закрыта пользователь может вызвать onDestroy, и ваш широковещательный приемник может не быть активен во время прослушивания уведомления пользователем. Если вы вообще не отменяете регистрацию, может показаться, что это работает, но это утечка памяти, GC может очистить в любое время, что может привести к сбою в вашей программе, т. е. вы должны отменить регистрацию. Если вам нужно перейти с подхода радиовещательного приемника, нужно иметь сервис для этого и приходит услуги с использованием собственных ошибок -> перезагрузка системы, разряд батареи и т. д. Я бы настоятельно рекомендую использовать первый подход.


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

заменить на android:enabled="false" to android:enabled="true"

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


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

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