android - 服务内的 BroadcastReceiver 未处理通知操作的广播

标签 android android-service android-notifications android-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. 然后我们在服务的 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() 永远不会被调用。该服务是连续的,并且在 Notification 操作发送广播时处于 Activity 状态。由于广播的性质,我无法对其进行调试,因此我有点受阻。

最佳答案

您正在为 PendingIntent 创建此显式 Intent:

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

这有几个原因行不通。显式 Intent - 那些为特定目标类创建的 - 不适用于动态注册的 Receiver 实例。此外,这是针对错误的类。带有 Service 类目标的广播 Intent 将完全失败。 getBroadcast() PendingIntent 需要一个 BroadcastReceiver 类作为目标。

根据您当前的设置 - 动态注册的 Receiver 实例 - 您需要使用隐式 Intent;即,带有操作 StringIntent,而不是目标类。例如:

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

然后,您可以将 String 操作用于要用来注册 Receiver 的 IntentFilter

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

请注意,IntentFilter 可以有多个操作,因此您可以注册一个 Receiver 来处理多个不同的操作。


或者,您可以坚持使用显式 Intent,并在 list 中静态注册一个 BroadcastReceiver 类。例如:

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

在 list 中:

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

那么您的Intent 将类似于:

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

但是,这需要一个额外的步骤,因为您随后需要以某种方式将广播信息从 NotificationReceiver 传递到 Service;例如,使用事件总线、LocalBroadcastManager

关于android - 服务内的 BroadcastReceiver 未处理通知操作的广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41649960/

相关文章:

android - 以编程方式设置 fragment 类中的 WebView loadUrl

android - 将 Canvas 上的图像保存到 SurfaceView 中的文件

android - 服务和处理程序之间的关系

android - 从 Activity 启动服务

android - 升级到Android 8.1后startForeground失败

Android Notification Builder 不播放自定义声音

android - 当呈现模态、iOS Actionsheet、选择器组件时,React Native 上的 float 按钮 (FAB) 不会停留在顶部

android - 在 Android 中,当使用传感器收集数据时,我应该使用 IntentService 还是 Service?

android - 从服务恢复 android Activity

Android:如果将 Activity 带回屏幕,Notification 的 PendingIntent 不会触发 onCreate()