Android15-解决后台无法启动应用App问题

Android15 版本解决后台无法启动应用问题

文章目录


前言-需求

  • 这里进行总结这个问题的目的,为了后续静默安装并重启静默安装的应用做铺垫;
  • 在Android15 非 HOME 应用,发现第三方应用、系统应用 后台启动另外一个APP ,发现无效。 这就导致静默安装的应用 无法自动启动【需求是:静默安装应用成功后,自动启动安装的应用】。

现象

比如如下,启动一个App,居然无法启动。

在静默安装后,去启动这个应用,如下简单代码:发现总是失败! 如果写一个demo ,点击启动一个应用,绝对OK的。

java 复制代码
  private void launchApp(String appPackageName) {
        Log.d(TAG,"=======launchApp========appPackageName:"+appPackageName);
        Intent mLaunchIntent = mContext.getPackageManager().getLaunchIntentForPackage(appPackageName);
        if (mLaunchIntent != null) {
            Log.d(TAG, "launch app--->  appPackageName:"+appPackageName);
            if (mLaunchIntent.resolveActivity(mContext.getPackageManager()) != null) {
                Log.d(TAG, "launch app--->  startActivity ");
                try {
                    mLaunchIntent.addFlags(
                            Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    mContext.startActivity(mLaunchIntent);
                } catch (ActivityNotFoundException | SecurityException e) {
                    Log.e(TAG, "Could not start activity", e);
                }
            } else {
                Log.e(TAG, "No activity found to handle the intent for: " + appPackageName);
            }
        }else{
            Log.d(TAG,"===============qidong failed========");
        }
    }

问题

以前在HOME程序、MTK Android12/13 上面没有问题的,这次在RK3576 平台 Android15 版本,发现无法正常启动。 这里要解决的就是Android15 后台启动应用问题。

报错如下:

一、修改文件

路径:/frameworks/base/services/core/java/com/android/server/wm/BackgroundActivityStartController.java

二、实现方案

checkBackgroundActivityStart 方法中,直接返回允许:BalVerdict.ALLOW_BY_DEFAULT,代码如下;

1、实现全局去除拦截-所有应用都不检查

java 复制代码
 
  BalVerdict checkBackgroundActivityStart(
            int callingUid,
            int callingPid,
            final String callingPackage,
            int realCallingUid,
            int realCallingPid,
            WindowProcessController callerApp,
            PendingIntentRecord originatingPendingIntent,
            BackgroundStartPrivileges forcedBalByPiSender,
            ActivityRecord resultRecord,
            Intent intent,
            ActivityOptions checkedOptions) {
				
				
		// modify by fangchen  start 		
		 if(true){
            
			 Slog.d(TAG, " to set default as default=====================");
           return BalVerdict.ALLOW_BY_DEFAULT;
		 }			 
	   
	    // modify by fangchen  end  		
	

      ......................
        return abortLaunch(state);
    }
 

2、实现某个单独App 后台启动不检查

这里再次看日志打印[如上] 和 实际代码:先分析代码: 可以看到 需要启动的类在Intent ,又在 BalState 参数封装着的。

找到日志打印地方 和 日志展示,如下:BackgroundActivityStartController 类, abortLaunch 方法

三、需求实现-思路

1、搜索关键日志-找到关键的类BackgroundActivityStartController

如上,无法在后台App中打开第三方应用,报错日志再次提出来,如下:Background activity launch blocked! [

搜索关键日志,在源码周公搜索:grep -rn "Background activity launch blocked" ,结果如下: 找到 BackgroundActivityStartController

2、通过类-方法找到核心代码-checkBackgroundActivityStart

如上找到 BackgroundActivityStartController 日志打印地方:abortLaunch 方法,搜索abortLaunch 方法,发现都是在checkBackgroundActivityStart 方法中调用的

3、通过搜索关键方法checkBackgroundActivityStart-找到使用过的类

搜索大法:grep -rn "checkBackgroundActivityStart(",找到几个调用的类,如下:

涉及到的类路径,小结如下:

java 复制代码
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/AppTaskImpl.java
/frameworks/base/services/core/java/com/android/server/wm/BackgroundActivityStartController.java

4、分析各个类是如何调用方法-checkBackgroundActivityStart

ActivityStarter-checkBackgroundActivityStart 类方法调用

这里有个提示 ,如果: balVerdict = BalVerdict.ALLOW_BY_DEFAULT,注释:Sets ALLOW_BY_DEFAULT as default value as the activity launch will be aborted anyway. ,如果设置当前默认DEFAULT 值,那么将永远不再aborted

所以: 这里大胆猜测,让 checkBackgroundActivityStart 方法,返回 BalVerdict.ALLOW_BY_DEFAULT 即可。

再看看这个DEFAULT 是啥子,如下定义:就是一个静态对象,所以 直接调用即可。

ActivityTaskManagerService-checkBackgroundActivityStart 类方法调用

代码如下,解决方案,把相关代码屏蔽掉:

AppTaskImpl-checkBackgroundActivityStart 类方法调用

代码如下,解决方案,把相关代码屏蔽掉:就是不要执行相关逻辑检查

解决方案小结-BackgroundActivityStartController 类进行默认值即可

如上相关源码分析,最终解决方案直接在BackgroundActivityStartController 类中,创建BalVerdict 对象的方法checkBackgroundActivityStart,直接返回:BalVerdict.ALLOW_BY_DEFAULT,如下:

四、知识点扩展

BackgroundActivityStartController 初识

看类注释和方法:这个类其实就是启动Activity 前各种权限检查。 这里不仅仅是当前需求的检查,是否BalState 允许,还有是否HOME APPuid/systemUid

实现类似功能,您需要使用替代方案。以下是几种主流方法的对比

方法 核心原理 适用场景与关键要求 备注
1. 前台服务 + 通知 启动一个前台服务,并显示一个带setFullScreenIntent的通知。系统在特定条件(如通知触发)下允许全屏启动。 用户必须授予 USE_FULL_SCREEN_INTENT 权限。适用于来电、闹钟等需要强用户感知的场景。 官方推荐方案,兼容性最好。
2. 引导用户开启特定权限 引导用户在系统设置中手动开启针对本应用的"后台弹出界面"或"显示在其他应用上层"等权限。 因设备厂商(小米、华为等)而异,权限名称和入口不统一,需要单独适配。 在非原生系统上常用,但对用户体验有干扰。
3. 在系统允许的特殊情况下启动 利用系统允许后台启动Activity的少数例外情况,如来电、闹钟、地理围栏、用户点击通知/PendingIntent等。 严格受限于系统规定的场景,无法由应用任意触发。 最合规的方案,但功能受限,非通用解法。

总结

  • 这里解决了一个Android15 版本后台启动App 问题,日常如果用HOME程序启动、Framework 层启动不会有问题,但是如果是第三方App后台会有问题
  • 重点是分析问题思想步骤,现在也不能说对 BackgroundActivityStartController 了解多少,但核心问题是分析问题、并解决问题思路很重要。
  • 这里为了解决 静默安装最后启动的一个步骤,方便静默安装更深的理解,后续再写一下笔记,方便查阅。