0

Я пытаюсь создать уведомление во время работы службы воспроизведения музыки и использовать уведомление для взаимодействия с сервисом (воспроизведение, пауза, остановка) с использованием механизма Broadcast.Передача по уведомлению Действие, которое не обрабатывается в BroadcastReceiver внутри службы

(Я знаю, что есть возможность использовать PendingIntent.getService() в качестве кнопки действия в уведомлении, но мне не нравится эта идея, потому что это вызовет onStartCommand() службы, и я необходимо проанализировать и проанализировать объект Intent для принятия мер, что кажется не таким чистым, как подход BroadcastReceiver, описанный ниже).

Давайте проиллюстрируем то, что у нас есть до сих пор с некоторым (усеченным) кодом.

  1. Мы создания объекта Notification внутри жизненного цикла сервиса, добавьте кнопку действия, и показывать уведомления с помощью startForeground().

    ... 
    Intent i = new Intent(getBaseContext(), PlayerService.class); 
    PendingIntent piStop = PendingIntent.getBroadcast(getBaseContext(), 1, i, PendingIntent.FLAG_ONE_SHOT); 
    NotificationCompat.Action actionStopPlayback = new NotificationCompat.Action(R.drawable.ic_stop_white_36dp, "Stop playback", piStop); 
    notification.addAction(actionStopPlayback); 
    ... 
    
  2. Тогда мы регистрации BroadcastReceiver внутри OnCreate() службы (и регистрацией его в OnDestroy конечно, это более простой пример).

    IntentFilter intentFilter = new IntentFilter(); 
    registerReceiver(new BroadcastReceiver() { 
        @Override 
        public void onReceive(Context context, Intent intent) { 
         Log.d(getClass().toString(), "Broadcast received"); 
        } 
    }, intentFilter); 
    

И конечный результат в том, что OnReceive() приемника никогда не вызывается. Услуга является непрерывной и активна, когда действие «Уведомление» отправляет широковещательную передачу. Поскольку у меня нет возможности отлаживать трансляции из-за их характера, я как бы заблокирован здесь.

+0

Я использовал механизм, в котором Уведомление отправляет широковещательную передачу в BroadcastReceiver «A». Этот BroadcastReceiver «A» отправляет трансляцию во внутреннюю (внутреннюю службу) BroadcastReceiver «B». В B onReceive() я обрабатываю задачу. Вот [пример github repo] (https://github.com/rupinderjeet/NotificationActionButtonExample/tree/master/app/src/main/java/com/rupinderjeet/notificationactionbuttonexample) Я сделал для другого ответа. ** См. Ответ Майка **. – rupinderjeet

ответ

3

Вы создаете этот явный Intent для PendingIntent:

Intent i = new Intent(getBaseContext(), PlayerService.class); 

Это не будет работать в течение нескольких причин. Явные Intent s - созданные для определенного целевого класса - не работают с динамически зарегистрированными экземплярами приемника. Кроме того, это нацеливается на неправильный класс. Передача Intent с целевым классом цели Service просто прекратится. A getBroadcast()PendingIntent в качестве цели понадобится класс BroadcastReceiver.

С вашей текущей настройкой - динамически зарегистрированный экземпляр получателя - вам нужно будет использовать неявный Intent; то есть Intent с действием String, а не целевым классом. Например:

Intent i = new Intent("com.hasmobi.action.STOP_PLAYBACK"); 

Вы бы затем использовать это действие String для IntentFilter вы используете, чтобы зарегистрировать приемник.

IntentFilter intentFilter = new IntentFilter("com.hasmobi.action.STOP_PLAYBACK"); 

Обратите внимание, что IntentFilter может иметь несколько действий, так что вы можете зарегистрировать один приемник для обработки несколько различных действий.


В качестве альтернативы, вы можете придерживаться с помощью явного Intent и статически зарегистрировать BroadcastReceiver класс в манифесте.Например:

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

В манифесте:

<receiver android:name=".NotificationReceiver" /> 

Тогда ваш Intent будет выглядеть следующим образом:

Intent i = new Intent(PlayerService.this, NotificationReceiver.class); 

Однако, для этого потребуется дополнительный шаг, как вы тогда должны как-то передавать информацию о трансляции от NotificationReceiver до Service; например, с шиной события, LocalBroadcastManager и т. д.

+1

Wow я пытался понять это в течение нескольких часов, что неявное намерение именно то, что я искал Спасибо! – Gallo2fire