我希望通知管理器显示一个弹出窗口,其中有一个“X”按钮可以关闭它。 关闭时,我希望 BroadcastReceiver 在已注册接收器和通知的服务上调用一个方法,并且是容器。
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);
我发现必须在 list 中静态定义 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 触发另一个 Intent ,但这似乎是另一场接力赛——一个 BroadcastReceiver 连接到另一个 BroadcastReceiver。我还听说广播可以延迟。
那么我的 BroadcastReceiver 如何与服务通信?
最佳答案
When I tried to dynamically register the receiver, it was not called at all when notification was fired.
我假设此 Notification
用于前台服务。如果是这样,如果您的 Intent
与您的 IntentFilter
匹配,那么动态注册的接收器应该可以工作,尽管您可能需要调用 setPackage()
Intent
绕过 Android 8.0+ 上的隐式广播禁令。
But then I also found that my Receiver could not invoke any methods in myService because trying to cast context in onReceive()
传递给 onReceive()
的 Context
将与您应用的任何其他组件无关。
So how does my BroadcastReceiver communicate with the Service?
如果 Notification
应该只在服务运行时存在,您应该切换回动态注册方法。或者,使用 PendingIntent
的 getService()
版本直接与您的 Service
对话。 getService()
PendingIntent
将在您的 Service
上触发 onStartCommand()
,您可以将内容放入 Intent
告诉您要做什么,例如您的 setAction(CLOSE_BUTTON_ACTION)
调用。 Intent
需要识别您的服务,而不是识别 BroadcastReceiver
。
如果服务未运行时可能存在通知
,则:
- 使用我上面提到的
getService()
PendingIntent
,或者 - 使用
BroadcastReceiver
的onReceive()
中的startService()
启动服务(如果尚未启动)并触发onStartCommand()
(让你做你应该做的事)
关于android - 当 ReceiverRestrictedContext 无法转换为 MyService 时,BroadcastReceiver 如何与 Service 通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53572149/