我正在尝试在音乐播放服务运行时构建通知,并使用通知使用广播机制与服务进行交互(播放,暂停,停止).
(我知道也有可能在通知中使用PendingIntent.getService()作为操作按钮,但我不喜欢这个想法,因为这会触发服务的onStartCommand(),我需要解析和分析Intent对象采取行动,看起来不像BroadcastReceiver那样干净,如下所述.
让我们用一些(截断的)代码来说明我们到目前为止所拥有的内容.
我们在服务生命周期内创建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); ...
然后我们在服务的onCreate()中注册一个BroadcastReceiver(当然在onDestroy中取消注册它;这是一个更简化的例子).
IntentFilter intentFilter = new IntentFilter(); registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(getClass().toString(), "Broadcast received"); } }, intentFilter);
最后的结果是接收器的onReceive()永远不会被调用.该服务是连续的,并且在通知操作发送广播时处于活动状态.由于我的性质无法调试广播,我在这里被封锁了.
您正在Intent
为以下内容创建此明确的PendingIntent
:
Intent i = new Intent(getBaseContext(), PlayerService.class);
由于几个原因,这不起作用.显式Intent
s - 为特定目标类创建的 - 不适用于动态注册的Receiver实例.此外,这是针对错误的类.Intent
具有Service
类目标的广播将彻底失败.A getBroadcast()
PendingIntent
需要一个BroadcastReceiver
类作为目标.
使用您当前的设置 - 动态注册的Receiver实例 - 您将需要使用隐式Intent
; 即,一个Intent
有动作String
,而不是一个目标类.例如:
Intent i = new Intent("com.hasmobi.action.STOP_PLAYBACK");
然后,您可以使用该动作String
为IntentFilter
你使用注册的接收器.
IntentFilter intentFilter = new IntentFilter("com.hasmobi.action.STOP_PLAYBACK");
请注意,IntentFilter
可以有多个操作,因此您可以注册一个Receiver来处理多个不同的操作.
或者,您可以坚持使用显式Intent
,并BroadcastReceiver
在清单中静态注册一个类.例如:
public class NotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ... } }
在清单中:
然后你Intent
会类似于:
Intent i = new Intent(PlayerService.this, NotificationReceiver.class);
但是,这需要一个额外的步骤,因为您需要以某种方式将广播信息传递NotificationReceiver
给Service
; 例如,使用事件总线LocalBroadcastManager
等