我的应用程序(targetSdk = 25)在清单中定义了一个广播接收器,如下所示:
<receiver android:name="my.package.DownloadManagerReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
每当Android DownloadManager下载完文件时,我的DownloadManagerReceiver
就会收到通知,因此我可以对下载的文件进行一些处理。
我正在将应用程序的targetSdk迁移到27(奥利奥)。根据{{3}},通过清单注册的隐式广播接收器不应在Android O中工作(https://developer.android.com/about/versions/oreo/background#broadcasts除外)。
但是,当我使用运行Android 8.0和targetSdk = 27的仿真器运行我的应用程序时,下载完成后,DownloadManager仍会通知清单中定义的广播接收器。
我试图找到DownloadManager发送其广播的源代码,以了解其如何发送其广播,但我找不到它。
有人知道android.intent.action.DOWNLOAD_COMPLETE
是显式广播而不是隐式广播吗?为什么我的接收器仍在接收该广播?
答案 0 :(得分:5)
这是我进一步研究平台的源代码后发现的:
1)实例化DownloadManager时,它会保留对应用程序上下文的引用,并从该上下文中提取应用程序的程序包名称
2)当请求下载时,该软件包名称被插入下载数据库的Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE
列中
3)下载完成后,DownloadInfo.sendIntentIfRequested()方法将调用Intent.setPackage()并传递软件包名称。根据{{3}}:
(通常为可选),设置一个明确的应用程序包名称,该名称应 限制此Intent将解决的组件。如果留给 默认值为null,所有应用程序中的所有组件将 考虑过的。如果非空,则Intent只能与 给定的应用程序包。
基于该描述,我的理解是广播意图将针对我的应用,因此可以作为明确意图。