无法将ReceiverRestrictedContext强制转换为MyService时,BroadcastReceiver如何与Service通信?

时间:2018-12-01 15:12:12

标签: android

我希望通知管理器显示一个弹出窗口,该弹出窗口具有一个“ X”按钮以将其关闭。 当关闭时,我希望BroadcastReceiver在Service上调用已注册接收者和通知的方法,该方法是容器。

RemoteViews remoteView =  createPopupView();
Intent intent = new Intent(myService, MyReceiver.class);
intent.setAction(CLOSE_BUTTON_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(myService,
        MY_POPUP_ID, intent, 0);
remoteView.setOnClickPendingIntent(R.id.img_close_selector, pendingIntent);
builder.setContent(remoteView);

我发现MyReceiver必须在清单中静态定义。 当我尝试动态注册接收器时,在触发通知时根本没有调用它。 但是后来我又发现我的Receiver无法调用myService中的任何方法,因为试图在onReceive()中强制转换上下文,

((MyService)context).foo();

((MyService) getApplicationContext()).foo()

原因...

    AndroidRuntime: java.lang.RuntimeException: 
Unable to start receiver com.myco.MyClass$MyReceiver: java.lang.ClassCastException: 
android.app.ReceiverRestrictedContext cannot be cast to com.myco.MyService

我想我可以从BroadcastReceiver发出另一个意图,但似乎又是一场接力比赛-一个BroadcastReceiver挂接到另一个BroadcastReceiver。我也听说广播可能会延迟。

那么我的BroadcastReceiver如何与服务通信?

1 个答案:

答案 0 :(得分:1)

  

当我尝试动态注册接收者时,在触发通知时根本没有调用它。

我假设此Notification用于前台服务。如果是这样,尽管您的Intent与您的IntentFilter相匹配,则动态注册的接收器应该可以工作,尽管您可能需要在setPackage()上调用Intent才能通过隐式广播禁止使用Android 8.0 +。

  

但是后来我也发现我的Receiver无法调用myService中的任何方法,因为试图在onReceive()中强制转换上下文

传递给Context的{​​{1}}与应用程序的任何其他组件无关。

  

那么我的BroadcastReceiver如何与服务通信?

如果onReceive()仅在服务运行时存在,则应切换回动态注册方法。或者,使用Notification的{​​{1}}版本直接与您的getService()对话。 PendingIntent Service会在您的getService()上触发PendingIntent,您可以将东西放入onStartCommand()中以告诉您要做什么,例如您的{{ 1}}呼叫。不过,Service需要标识您的服务,而不是Intent

如果在服务未运行时setAction(CLOSE_BUTTON_ACTION)可能存在,则可以:

  • 使用我上面提到的Intent BroadcastReceiver,或者
  • 使用NotificationgetService()中的PendingIntent启动服务(如果尚未启动)并触发startService()(您可以执行任何操作)你应该在做)