开机广播使用说明
开机广播(BOOT_COMPLETED)是一种特殊的广播,用于在设备启动完成后通知应用程序。本文将介绍如何使用开机广播以及相关注意事项。
配置 Manifest 文件
在应用的 Manifest.xml 文件中,需要添加以下内容来配置开机广播:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <receiver android:name=".BootBroadcastReceiver"> <intent-filter android:priority="2000"> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
上述代码中,我们首先添加了 RECEIVE_BOOT_COMPLETED 权限,然后定义了一个 BootBroadcastReceiver 类作为接收器。在接收器的 intent-filter 中,我们指定了 action 为 BOOT_COMPLETED,并设置了优先级为 2000。
创建 BootBroadcastReceiver 类
创建一个 BootBroadcastReceiver 类并继承自 BroadcastReceiver。在 onReceive 方法中,你可以编写处理开机广播的逻辑。
public class BootBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 在此处添加处理开机广播的逻辑 } }
在 onReceive 方法中,你可以执行你需要在设备启动完成后执行的操作。
注意事项
以下是一些与开机广播相关的注意事项:
- 如果应用安装在 SD 卡上,将无法接收到 BOOT_COMPLETED 广播(这种情况出现的概率较低)。
- 对于 Android 3.1 及更高版本,如果要接收开机广播,有两种方法:
- 将应用预置到 /system/app/ 目录中。
- 在应用安装后首次启动应用,之后就能正常接收到广播了。适用于带有 Activity 的应用。
注释
- BOOT_COMPLETED 比较特殊,只有预置到 /system/app/ 目录下的 APK 才能通过 android.intent.action.BOOT_COMPLETED 实现开机自启动。
预置到 /data/app/ 或 /vendor/app/ 目录下的第三方 APK,如果在安装后从未启动过或者被用户手动停止过,它会处于“stopped state”(应用信息保存在 /data/system/users/0/package-restrictions.xml 中),此时其接收器将无法接收到任何广播,因此无法在开机后自动启动。
但是一旦用户手动点击启动了该应用程序,下次开机时它肯定会自动启动,并接收到 BOOT_COMPLETED 广播。 - 同时,系统增加了两个 Flag:FLAG_INCLUDE_STOPPED_PACKAGES 和 FLAG_EXCLUDE_STOPPED_PACKAGES,用于标识一个 Intent 是否激活处于“stopped state”的应用。
- Google 允许应用和后台服务通过给广播 Intent 设置 FLAG_INCLUDE_STOPPED_PACKAGES 来唤醒处于“stopped state”的程序,也就是说,用户自己编写的广播 Intent 可以控制这种机制。但是系统自带的广播 Intent 默认都是 FLAG_EXCLUDE_STOPPED_PACKAGES,无法修改,因此无法通过系统广播来实现自启动。
应用无法收到开机广播和 SD 卡 MOUNTED 广播的解决方法
- 权限检查。
- 对于安装在 SD 卡上的应用,只有在收到开机广播后才会挂载 SD 卡,因此无法收到开机广播。解决方法如下:
- 在应用的主配置文件中增加限制,不安装到 SD 卡中,设置
android:installLocation="internalOnly"
。 - 配合 SD 卡挂载广播使用,因为挂载不一定是开机广播。
- 若还是无法接受到开机广播,则可以查看设置--安全--自启动管理--允许系统唤醒。
我在尝试第三步时,问题解决,特此备注。
在广播发送的前序步骤(位于AMS)里,通过 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 设置了标识,以声明广播不发给已停止的进程,层层调用后最终在 IntentResolver 的 buildResolveList 方法中实现过滤。
其他说明
在尝试将应用预置到已有固件中进行工厂测试时,遇到了两个问题:
- 预置到可卸载分区后,应用无法接收任何广播。
- 使用 FwFactoryTool_V5.52 工具(该工具是基于 RK3399 10.0 代码开发的)将 APK 预置进固件时失败。
对于上述问题,有以下补充说明:
- 只有预置 APK 能够正常接收广播,内置 APK 和内置 priv-app 都不行。
- 在安装应用到 SD 卡的情况下,应用在接收开机广播前会挂载 SD 卡,因此无法接收到开机广播。
解决方法: