前台服务豁免的源码阅读记录(Android 12版本)

Android12对后台启动前台服务增加了严格限制,包括进程状态、权限检查等多个方面。当targetSdkVersion为31及以上时,不满足特定条件的应用将无法直接启动前台服务,会抛出异常。解决方法包括使用精确闹钟、取消电池优化、获取系统弹窗权限等。此外,还详细列举了各种豁免启动前台服务的情况。

Android 12 对前台服务增加了一些限制,在为 target 31 适配过程中阅读了一些AOSP的系统源码,本文用于记录这些阅读。

当应用在禁止启动前台服务的情况下调用Service.startForegroundContext.startForegroundService方法时会出现ForegroundServiceStartNotAllowedException异常,这个异常只有在应用的targetSdkVersion在31以上时会出现

而在后台启动前台服务的豁免情况在ActiveService.shouldAllowFgsStartForegroundLocked方法中的有描述,具体情况如下:

  1. 进程为 PROCESS_STATE_TOP (进程持有当前的顶层activity。注意,这涵盖了所有对用户可见的activity。或者该进程为系统进程)
final int uidState = mAm.getUidStateLocked(callingUid);
// Is the calling UID at PROCESS_STATE_TOP or above?
if (uidState <= PROCESS_STATE_TOP) {
   
   
    ret = getReasonCodeFromProcState(uidState);
}
/** @hide Process is hosting the current top activities.  Note that this covers
  * all activities that are visible to the user. */
@UnsupportedAppUsage
@TestApi
public static final int PROCESS_STATE_TOP = ProcessStateEnum.TOP;
  1. 当前进程状态允许启动前台服务(PROCESS_STATE_BOUND_FOREGROUND_SERVICE相关,Process is hosting a foreground service due to a system binding.) | 进程或应用有从后台启动前台服务的权限START_FOREGROUND_SERVICES_FROM_BACKGROUND(这个权限第三方不可用,仅限系统app) | 应用到后台没超过5秒(DEFAULT_FG_TO_BG_FGS_GRACE_DURATION常量控制)
if (ret == REASON_DENIED) {
   
   
    final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> {
   
   
        if (app.uid == callingUid) {
   
   
            final ProcessStateRecord state = app.mState;
            if (state.isAllowedStartFgsState()) {
   
   
                return getReasonCodeFromProcState(state.getAllowStartFgsState());
            } else {
   
   
                final ActiveInstrumentation instr = app.getActiveInstrumentation();
                if (instr != null
                        && instr.mHasBackgroundForegroundServiceStartsPermission) {
   
   
                    return REASON_INSTR_BACKGROUND_FGS_PERMISSION;
                }
                final long lastInvisibleTime = app.mState.getLastInvisibleTime();
                if (lastInvisibleTime > 0 && lastInvisibleTime < Long.MAX_VALUE) {
   
   
                    final 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值