Android Oreo(api 26)无法接收来自其他模块的广播

Android Oreo(api 26)无法接收来自其他模块的广播,android,broadcastreceiver,android-8.0-oreo,Android,Broadcastreceiver,Android 8.0 Oreo,我有一个模块,将用于下载,一旦文件下载,我用来发送一个隐式brodcast。 在我的应用程序模块中,一旦下载完成,广播接收器将进行一些更改设置。 在android 8中,我无法接收此广播,检查文档,据说使用显式意图new intent(上下文,MyBroadcastReceiver.class); 但我的问题是我的MyBroadcastReceiver.class在我的应用程序模块中,而不是在下载模块中,所以我不能这样做 其他的可能性是什么?我一直在使用这个新的广播实现…请先使用请先使用如果你真

我有一个模块,将用于下载,一旦文件下载,我用来发送一个隐式brodcast。 在我的应用程序模块中,一旦下载完成,广播接收器将进行一些更改设置。 在android 8中,我无法接收此广播,检查文档,据说使用显式意图new intent(上下文,MyBroadcastReceiver.class); 但我的问题是我的MyBroadcastReceiver.class在我的应用程序模块中,而不是在下载模块中,所以我不能这样做

其他的可能性是什么?我一直在使用这个新的广播实现…

请先使用

请先使用

如果你真正的意思是“模块”-并且所有这些代码都在一个应用程序和一个进程中-请停止使用系统广播。使用过程中解决方案:

  • LocalBroadcastManager
    ,如Balu所建议
  • 绿色机器人事件总线
  • LiveData
  • RxJava
  • 等等
使用系统广播会影响隐私、安全和性能

但是,让我们假设“模块”是指“应用程序”,否则代码将在单独的进程中,因此进程内解决方案将无法工作

但我的问题是我的MyBroadcastReceiver.class在我的应用程序模块中,而不是在下载模块中,所以我不能这样做

如果收件人已在清单中注册,您当然可以使用
PackageManager
querybroadcasreceiver()
获取收件人的详细信息。然后,在发送广播之前,您可以在
Intent
上调用
setComponentName()
,使其明确:

private static void sendImplicitBroadcast(Context ctxt, Intent i) {
  PackageManager pm=ctxt.getPackageManager();
  List<ResolveInfo> matches=pm.queryBroadcastReceivers(i, 0);

  for (ResolveInfo resolveInfo : matches) {
    Intent explicit=new Intent(i);
    ComponentName cn=
      new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
        resolveInfo.activityInfo.name);

    explicit.setComponent(cn);
    ctxt.sendBroadcast(explicit);
  }
}
private static void sendImplicitBroadcast(上下文ctxt,意图i){
PackageManager pm=ctxt.getPackageManager();
列表匹配=pm.queryBroadcastReceivers(i,0);
for(ResolveInfo ResolveInfo:matches){
明确意图=新意图(i);
组件名称cn=
新组件名称(resolveInfo.activityInfo.applicationInfo.packageName,
resolveInfo.activityInfo.name);
explicit.setComponent(cn);
发送广播(显式);
}
}
请参阅以了解更多信息。

首先,如果您真正的意思是“模块”-并且所有这些代码都在单个应用程序和单个进程中-请停止使用系统广播。使用过程中解决方案:

  • LocalBroadcastManager
    ,如Balu所建议
  • 绿色机器人事件总线
  • LiveData
  • RxJava
  • 等等
使用系统广播会影响隐私、安全和性能

但是,让我们假设“模块”是指“应用程序”,否则代码将在单独的进程中,因此进程内解决方案将无法工作

但我的问题是我的MyBroadcastReceiver.class在我的应用程序模块中,而不是在下载模块中,所以我不能这样做

如果收件人已在清单中注册,您当然可以使用
PackageManager
querybroadcasreceiver()
获取收件人的详细信息。然后,在发送广播之前,您可以在
Intent
上调用
setComponentName()
,使其明确:

private static void sendImplicitBroadcast(Context ctxt, Intent i) {
  PackageManager pm=ctxt.getPackageManager();
  List<ResolveInfo> matches=pm.queryBroadcastReceivers(i, 0);

  for (ResolveInfo resolveInfo : matches) {
    Intent explicit=new Intent(i);
    ComponentName cn=
      new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName,
        resolveInfo.activityInfo.name);

    explicit.setComponent(cn);
    ctxt.sendBroadcast(explicit);
  }
}
private static void sendImplicitBroadcast(上下文ctxt,意图i){
PackageManager pm=ctxt.getPackageManager();
列表匹配=pm.queryBroadcastReceivers(i,0);
for(ResolveInfo ResolveInfo:matches){
明确意图=新意图(i);
组件名称cn=
新组件名称(resolveInfo.activityInfo.applicationInfo.packageName,
resolveInfo.activityInfo.name);
explicit.setComponent(cn);
发送广播(显式);
}
}

有关详细信息,请参阅。

谢谢,我成功地使用了intent.setClassName(packageName,className);eventbus的问题是,我需要注册和注销,但我仍然希望在接收brodcast时执行一个操作,即使应用程序已在后台(因此事件总线将不适合)。我想我会有与LocalBroadcastManager相同的问题,需要检查一下one@Chol:“所以事件总线不适合”--它比您正在做的更适合。更好的办法是摆脱所有这些,在这些模块(例如RxJava)中的类之间进行更直接的通信。但使用事件总线,事件将不会被接收,因为当应用程序处于后台或被终止时,活动将被注销,但我仍然需要在下载完成后制作一些东西,即使应用程序不再存在。如果RxJava能满足我的需要,我会看看它,正如你所说的,如果我能避免系统brodcast,它将是better@Choi:“当应用程序处于后台或被终止时,活动将被注销,因此不会收到事件”--活动在Android中不会被“终止”(它们被销毁,进程被终止,仅此而已)。除此之外,没有理由更新不可见的活动。当它返回前台时,它可以进入最新状态。停止浪费CPU时间和电池寿命来更新不可见的内容。是的,请理解,一旦下载完成,我会将该文件设置为新的默认铃声。即使应用程序不再位于前台,也需要执行这部分代码。仅当使用eventBusThanks显示时,UI才会刷新。如果我成功使用intent.setClassName(packageName,className);eventbus的问题是,我需要注册和注销,但我仍然希望在接收brodcast时执行一个操作,即使应用程序已在后台(因此事件总线将不适合)。我想我会有与LocalBroadcastManager相同的问题,需要检查一下one@Chol:“所以事件总线不适合”--它比您正在做的更适合。更好的办法是摆脱所有这些,在这些模块(例如RxJava)中的类之间进行更直接的通信