永久性广播接收器

3
一个应用程序,我们称之为应用程序A,安装在我的手机上,产生非常有趣的数据。我无法控制应用程序A,但开发人员很好心地本地广播了有趣的信息,以便其他应用程序(如我正在构建的应用程序B)可以使用其他应用程序生成的数据。
我通过以下代码在MainActivityonResume()中注册一个BroadcastReceiver:
registerReceiver(new CustomBroadCastReceiver, new IntentFilter("com.intent.filter.DATA"));

这很好,但当我的应用程序被强制停止或由Android停止时(为了保护电源/释放内存?),就会出现问题。

然而,应用程序A整天整夜地产生数据。基于这些数据,应用程序B计算进一步的结果,并且应该在读数朝错误方向发展时发出警报。BroadcastReceiver必须在任何时间点都能够发出警报。

目前最佳实践是什么,以尽可能长时间地保持BroadcastReceiver的活动状态(甚至可以在用户通过强制停止应用程序时仍然保持活动状态)?

编辑:几个月后,我发现我的三星手机将我的应用程序放在一个省电列表中,该列表会强制而定期地关闭应用程序以节省电力。请确保您自己的手机上没有类似的列表中包含您的应用程序。


很棒的问题,表述清晰。只是需要注意一点:滑动并不等同于强制停止。 - Cornelius Roemer
2个回答

0

您需要在清单文件中注册接收器,而不是以编程方式。请参见: https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers

然而,如果您的目标是Oreo+,那么您将无法再这样做了。App A需要明确调用您的包才能接收到在App B的清单文件中声明的接收器广播。您可以在此处阅读有关此事的更多信息: https://developer.android.com/about/versions/oreo/android-8.0-changes#back-all

这不是您的应用程序共享数据的好方法(这也是Google逐步淘汰它的原因)。每次其他应用程序发生某些事情时,都必须将您的应用程序加载到内存中,这是低效的。想象一下数十个或数百个应用程序为各种广播执行相同的操作,以及对电池寿命的影响。

更好的方法是让App A在内容提供程序中公开数据,然后您的应用程序会(不频繁地)唤醒并拉取数据。


理论上,有什么阻止我每小时使用AlarmManager启动另一个BroadcastReceiver,并在此BroadcastReceiver中注册原始接收器的方法? - Marco7757
1
那行不通。一旦你的 onHandleIntent() 返回,从 Android 的角度来看,你的进程将成为被回收的顶级候选者,因为没有任何优先级。这需要的时间会有所不同。 - Jeffrey Blattman
原来Application 1的开发人员使用了我可以自由定义的字符串调用了setPackage()方法(Application 1是开源的)。因此,我将这个字符串设置为我的包名,并在清单文件中使用意图过滤器注册接收器。 然而,整晚接收器都没有更新。你有什么想法,为什么会这样?除了显式调用setPackage()之外,我还需要考虑其他什么吗? - Marco7757
我认为你需要使用 setComponent() 来完全限定目标组件。最好在 App 1 中添加一个钩子来强制发送广播,以便更轻松地测试它。或者创建一个测试工具,广播相同的意图。 - Jeffrey Blattman
如何使应用程序无限期地保持唤醒状态,而不会在一两天后被杀死? - Cornelius Roemer
@CorneliusRoemer 除非你的应用程序是系统应用程序,需要将其与系统映像一起安装,否则你无法做到。Android 是移动操作系统,不应该有足够的 RAM 来持续保留进程在内存中。你可以使用 JobScheduler 定期唤醒,或者监听隐式广播(或越来越少的明确广播集,你被允许在清单中监听)。 - Jeffrey Blattman

0

你需要在应用程序清单文件AndroidManifest.xml中注册你的BroadcastReceiver

<receiver android:name=".CustomBroadCastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="com.intent.filter.DATA"/>
    </intent-filter>
</receiver>

系统包管理器在应用安装时注册接收器。接收器成为您的应用程序的一个独立入口点,这意味着如果应用程序当前未运行,则系统可以启动应用程序并传递广播。 https://developer.android.com/guide/components/broadcasts#manifest-declared-receivers 这意味着即使您的应用程序关闭,系统也会启动您的广播接收器,除非用户强制停止了您的应用程序。 https://dev59.com/9mox5IYBdhLWcg3wYzUt#9240705 但是请注意,从Android 8.0(Oreo)开始,会应用一些限制。 https://developer.android.com/guide/components/broadcasts#changes-system-broadcasts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接