Android 12 对前台服务增加了一些限制,在为 target 31 适配过程中阅读了一些AOSP的系统源码,本文用于记录这些阅读。
当应用在禁止启动前台服务的情况下调用Service.startForeground或Context.startForegroundService方法时会出现ForegroundServiceStartNotAllowedException异常,这个异常只有在应用的targetSdkVersion在31以上时会出现
而在后台启动前台服务的豁免情况在ActiveService.shouldAllowFgsStartForegroundLocked方法中的有描述,具体情况如下:
- 进程为 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;
- 当前进程状态允许启动前台服务(
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

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

被折叠的 条评论
为什么被折叠?



