Android 预置可卸载分区接收不到任何广播问题分析和解决

简介: Android 预置可卸载分区接收不到任何广播问题分析和解决

开机广播使用说明

开机广播(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 方法中,你可以执行你需要在设备启动完成后执行的操作。

注意事项

以下是一些与开机广播相关的注意事项:

  1. 如果应用安装在 SD 卡上,将无法接收到 BOOT_COMPLETED 广播(这种情况出现的概率较低)。
  2. 对于 Android 3.1 及更高版本,如果要接收开机广播,有两种方法:
  • 将应用预置到 /system/app/ 目录中。
  • 在应用安装后首次启动应用,之后就能正常接收到广播了。适用于带有 Activity 的应用。

注释

  1. 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 广播。
  2. 同时,系统增加了两个 Flag:FLAG_INCLUDE_STOPPED_PACKAGES 和 FLAG_EXCLUDE_STOPPED_PACKAGES,用于标识一个 Intent 是否激活处于“stopped state”的应用。
  3. Google 允许应用和后台服务通过给广播 Intent 设置 FLAG_INCLUDE_STOPPED_PACKAGES 来唤醒处于“stopped state”的程序,也就是说,用户自己编写的广播 Intent 可以控制这种机制。但是系统自带的广播 Intent 默认都是 FLAG_EXCLUDE_STOPPED_PACKAGES,无法修改,因此无法通过系统广播来实现自启动。

应用无法收到开机广播和 SD 卡 MOUNTED 广播的解决方法

  1. 权限检查。
  2. 对于安装在 SD 卡上的应用,只有在收到开机广播后才会挂载 SD 卡,因此无法收到开机广播。解决方法如下:
  • 在应用的主配置文件中增加限制,不安装到 SD 卡中,设置 android:installLocation="internalOnly"
  • 配合 SD 卡挂载广播使用,因为挂载不一定是开机广播。
  1. 若还是无法接受到开机广播,则可以查看设置--安全--自启动管理--允许系统唤醒。

我在尝试第三步时,问题解决,特此备注。

在广播发送的前序步骤(位于AMS)里,通过 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 设置了标识,以声明广播不发给已停止的进程,层层调用后最终在 IntentResolver 的 buildResolveList 方法中实现过滤。

其他说明

在尝试将应用预置到已有固件中进行工厂测试时,遇到了两个问题:

  1. 预置到可卸载分区后,应用无法接收任何广播。
  2. 使用 FwFactoryTool_V5.52 工具(该工具是基于 RK3399 10.0 代码开发的)将 APK 预置进固件时失败。

对于上述问题,有以下补充说明:

  • 只有预置 APK 能够正常接收广播,内置 APK 和内置 priv-app 都不行。
  • 在安装应用到 SD 卡的情况下,应用在接收开机广播前会挂载 SD 卡,因此无法接收到开机广播。

解决方法:

  • 对于第一个问题,可以在 Manifest 文件中增加限制,不允许将应用安装到可卸载分区。
  • 对于第二个问题,可以尝试使用系统自带的预置工具进行 APK 的预置,或者寻找适用于 RK3288 8.1 代码的预置工具。
  • 参考1
  • 参考2
  • 参考3
相关文章
|
9天前
|
Java API 调度
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
54 0
|
9天前
|
存储 Java API
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
Android 浅度解析:mk预置AAR、SO文件、APP包和签名
101 0
|
9天前
|
存储 缓存 Android开发
android分区概述
android分区概述
96 0
|
9天前
|
Android开发
安卓的分区一点有用知识:super、lpunpack、lpdump
安卓的分区一点有用知识:super、lpunpack、lpdump
322 0
|
9天前
|
机器学习/深度学习 Java Shell
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
55 0
|
9天前
|
Shell Android开发
MT8385 Android AB分区系统升级(命令模式)
MT8385 Android AB分区系统升级(命令模式)
16 0
|
9天前
|
存储 缓存 Android开发
Android系统分区与升级
Android系统分区与升级
29 4
|
9天前
|
Java API Android开发
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
Android系统升级A/B分区OTA升级应用层调用UpdateEngine代码
29 0
|
9天前
|
调度 Android开发
Android9底部导航栏出现空白按钮问题分析
Android9底部导航栏出现空白按钮问题分析
18 0
|
9天前
|
存储 缓存 Linux
Android 系统的分区
Android 系统的分区
18 1