我正在尝试在音乐播放服务运行时构建通知,并使用通知使用广播机制与服务进行交互(播放,暂停,停止)。
(我知道也有可能在通知中使用PendingIntent.getService()作为操作按钮,但我不喜欢这个想法,因为这会触发onStartCommand()服务,我需要解析和分析Intent对象以采取行动,这似乎不像BroadcastReceiver方法那样干净,如下所述。
让我们用一些(截断的)代码来说明我们目前所拥有的内容。
我们在服务生命周期内创建通知对象,添加操作按钮,并使用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()。该服务是连续的,并且在通知操作发送广播时处于活动状态。由于我的性质无法调试广播,我在这里被阻止了。
答案 0 :(得分:5)
您正在为Intent
PendingIntent
Intent i = new Intent(getBaseContext(), PlayerService.class);
由于几个原因,这项工作没有成功。显式Intent
s - 为特定目标类创建的那些 - 不适用于动态注册的Receiver实例。此外,这是针对错误的类。具有Intent
类目标的广播Service
将彻底失败。 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) {
...
}
}
在清单中:
<receiver android:name=".NotificationReceiver" />
然后您的Intent
类似于:
Intent i = new Intent(PlayerService.this, NotificationReceiver.class);
但是,这需要一个额外的步骤,因为您需要以某种方式将广播信息从NotificationReceiver
传递到Service
;例如,使用事件总线LocalBroadcastManager
等