获取android 13

用户控制: 用户在长时间运行的应用程序上获得更多透明度和控制权:

  • 前台服务仍然需要包含通知,并且应用程序必须请求权限才能显示通知。
  • FGS 通知现在可以被用户关闭而不影响 FGS
  • 用户可以在任务管理器中查看长时间运行的应用列表
    • 任务管理器还允许用户停止应用程序

通知权限

介绍

权限定义

  1. android T 之前的通知:默认允许通知推送,需要用户跳转至多级设置页面去设置通知权限。
  2. android T新增前台服务的通知权限(运行时权限):

使用

权限使用

  1. android 13及以上: 应用自行控制权限对话框显示时间
  2. android 12L 及以下: 通常应用启动时弹框

豁免:与媒体会话有关的通知不受此行为变更的影响。

代码

在ServiceRecord的构造方法中会回调updateFgsHasNotificationPermission方法,去异步(避免死锁)从NMS中去获取此app是否有权限发送通知;ServiceRecord仅记录,具体权限校验在NMS中。

// ServiceRecord.java
// Whether FGS package has permissions to show notifications.
boolean mFgsHasNotificationPermission;private void updateFgsHasNotificationPermission() {// Do asynchronous communication with notification manager to avoid deadlocks.final String localPackageName = packageName;final int appUid = appInfo.uid;ams.mHandler.post(new Runnable() {public void run() {NotificationManagerInternal nm = LocalServices.getService(NotificationManagerInternal.class);if (nm == null) {return;}// Record whether the package has permission to notify the usermFgsHasNotificationPermission = nm.areNotificationsEnabledForPackage(localPackageName, appUid);}});
}

前台服务任务管理器

介绍

前台任务管理器
无论app的目标sdk版本是多少,android 13上都允许用户从抽屉式通知栏中停止前台服务(整个应用)。停止原因在ApplicationExitInfo表现为REASON_USER_REQUESTED。

豁免

以下应用可以运行前台服务,而完全不会显示在任务管理器中:

  • 系统级应用
  • 安全应用,即具有 ROLE_EMERGENCY 角色的应用
  • 处于演示模式的设备上的应用

当以下类型的应用运行前台服务时,它们会显示在 FGS 任务管理器中,但应用名称旁边没有可以供用户按的停止按钮:

  • 设备所有者应用
  • 资料所有者应用
  • 常驻应用
  • 具有 ROLE_DIALER 角色的应用
    • 处于doze白名单应用

代码

// FgsManagerController.kt
fun updateUiControl() {uiControl = when (activityManager.getBackgroundRestrictionExemptionReason(uid)) {// 不显示在任务管理器中PowerExemptionManager.REASON_SYSTEM_UID,PowerExemptionManager.REASON_DEVICE_DEMO_MODE -> UIControl.HIDE_ENTRY// 显示在任务管理器,但是没有停止按钮PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE,PowerExemptionManager.REASON_DEVICE_OWNER,PowerExemptionManager.REASON_DISALLOW_APPS_CONTROL,PowerExemptionManager.REASON_DPO_PROTECTED_APP,PowerExemptionManager.REASON_PROFILE_OWNER,PowerExemptionManager.REASON_PROC_STATE_PERSISTENT,PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI,PowerExemptionManager.REASON_ROLE_DIALER,PowerExemptionManager.REASON_SYSTEM_MODULE -> UIControl.HIDE_BUTTON// 正常情况else -> UIControl.NORMAL}uiControlInitialized = true
}
// AppRestrictionController.java
/*** @return The reason code of whether or not the given UID should be exempted from background* restrictions here.** <p>* Note: Call it with caution as it'll try to acquire locks in other services.* </p>*/
@ReasonCode
int getBackgroundRestrictionExemptionReason(int uid) {// uid < 10000if (UserHandle.isCore(uid)) {return REASON_SYSTEM_UID;}// Whitelist system appsif (isOnSystemDeviceIdleAllowlist(uid)) {return REASON_SYSTEM_ALLOW_LISTED;}// Whitelist user apps , doze白名单,可联系功耗同学添加if (isOnDeviceIdleAllowlist(uid)) {return REASON_ALLOWLISTED_PACKAGE;}// 暂无研究final ActivityManagerInternal am = mInjector.getActivityManagerInternal();if (am.isAssociatedCompanionApp(UserHandle.getUserId(uid), uid)) {return REASON_COMPANION_DEVICE_MANAGER;}// 处于演示模式的设备上的应用if (UserManager.isDeviceInDemoMode(mContext) {return REASON_DEVICE_DEMO_MODE;}final int userId = UserHandle.getUserId(uid);if (mInjector.getUserManagerInternal().hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)) {return REASON_DISALLOW_APPS_CONTROL;}// 设备所有者if (am.isDeviceOwner(uid)) {return REASON_DEVICE_OWNER;}// 资料所有者if (am.isProfileOwner(uid)) {return REASON_PROFILE_OWNER;}// persistent常驻应用final int uidProcState = am.getUidProcessState(uid);if (uidProcState <= PROCESS_STATE_PERSISTENT) {return REASON_PROC_STATE_PERSISTENT;} else if (uidProcState <= PROCESS_STATE_PERSISTENT_UI) {return REASON_PROC_STATE_PERSISTENT_UI;}final String[] packages = mInjector.getPackageManager().getPackagesForUid(uid);if (packages != null) {final AppOpsManager appOpsManager = mInjector.getAppOpsManager();final PackageManagerInternal pm = mInjector.getPackageManagerInternal();final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();for (String pkg : packages) {// VPNif (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN,uid, pkg) == AppOpsManager.MODE_ALLOWED) {return REASON_OP_ACTIVATE_VPN;} else if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN,uid, pkg) == AppOpsManager.MODE_ALLOWED) {return REASON_OP_ACTIVATE_PLATFORM_VPN;} else if (isSystemModule(pkg)) {return REASON_SYSTEM_MODULE;} else if (isCarrierApp(pkg)) {return REASON_CARRIER_PRIVILEGED_APP;} else if (isExemptedFromSysConfig(pkg)) {return REASON_SYSTEM_ALLOW_LISTED;} else if (mConstantsObserver.mBgRestrictionExemptedPackages.contains(pkg)) {return REASON_SYSTEM_ALLOW_LISTED;} else if (pm.isPackageStateProtected(pkg, userId)) {return REASON_DPO_PROTECTED_APP;} else if (appStandbyInternal.isActiveDeviceAdmin(pkg, userId)) {return REASON_ACTIVE_DEVICE_ADMIN;}}}// dialer角色if (isRoleHeldByUid(RoleManager.ROLE_DIALER, uid)) {return REASON_ROLE_DIALER;}if (isRoleHeldByUid(RoleManager.ROLE_EMERGENCY, uid)) {return REASON_ROLE_EMERGENCY;}return REASON_DENIED;
}

测试

adb shell dumpsys deviceidle // 查看是否在doze白名单,可以不显示停止按钮
adb shell cmd activity stop-app PACKAGE_NAME

监控长期运行的前台服务

介绍

长时间运行服务通知
如果系统检测到您的应用长时间运行某项前台服务(在 24 小时的时间段内至少运行 20 小时),便会发送通知邀请用户与前台服务 (FGS) 任务管理器互动。该通知包含以下内容:

APP is running in the background for a long time. Tap to review.

如果前台服务的类型为 FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK 或 FOREGROUND_SERVICE_TYPE_LOCATION,系统将不会显示此通知。

代码

  1. 谷歌提交记录
commit 64ac1a923065d38fa33789b315c716f4c93312fc
Author: Jing Ji <jji@google.com>
Date:   Sat Dec 11 03:14:45 2021 -0800Monitor long-running foreground servicesIf a certain package has foreground services running for a long time,say the accumulated durations over last X hours are more than Y hours,system will post a notification to remind the user.Some type of apps are subjected to be exempted, i.e. if it's alreadyin the device idle allowlist. More exemption could be added inthe follow-up CLs.Bug: 200326767Bug: 203105544Test: atest FrameworksMockingServicesTests:BackgroundRestrictionTestChange-Id: I3a8f34c33e7a533240abc7cf4fa569a0956eec73
  1. 主要逻辑在新增的类:
//  监控滥用(长时间运行)FGS 的跟踪器
frameworks/base/services/core/java/com/android/server/am/AppFGSTracker.java

显示长时间运行通知

static final long DEFAULT_BG_FGS_LONG_RUNNING_THRESHOLD = 20 * ONE_HOUR;

对应的流程如下:

移除长时间运行通知

若FGS已经停止运行则取消该通知

android T 前台Service相关推荐

  1. 前台Service发展历史

    启动和移除 启动 通常在Service的onStartCommand()方法中回调startForeground()方法,避免10s超时发生ANR. Context context = getAppl ...

  2. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 启动相同 id 的第二个前台 Service 关闭通知 )

    文章目录 一. 前台 Service 通知问题 二. 设置 startForeground id 参数为 0 三. 启动相同 id 的第二个前台 Service 关闭通知 1. 前台服务 1 2. 关 ...

  3. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 效果展示 | 源码资源 )

    文章目录 一. 使用前台 Service 提高应用进程优先级 1. 前台 Service 代码 2. 前台 Service 代码 3. 启动服务 二.效果展示 三.源码资源 一. 使用前台 Servi ...

  4. Android创建前台运行的Service

    Service如果要防止尽可能不被系统杀掉,需要设置为在前台运行. 由于设置前台运行service的方法在2.0之前和2.0之后有所变化. 所以需要根据不同的版本进行区分:或者完全使用反射机制来处理, ...

  5. Android 中的 Service 全面总结(转)

    转自:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html# Android 中的 Service 全面总结 1.Service的种 ...

  6. Android中的Service组件详解

    Service与Activity的区别在于:Service一直在后台运行,他没有用户界面,绝不会到前台来. 一,创建和配置Service 开发Service需要两个步骤:1,继承Service子类,2 ...

  7. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有什么 ...

  8. Android 2个Service实现相互保活,通过bindservice来实现,不通过广播实现

    1,实现原理:启动2个Service,相互绑定监听,当A Service监听到连接断开的时候,说明B服务可能被 Kill掉了,这时需要重新开启A服务,同样B服务的监听断掉了,重新启动A服务.A,B两个 ...

  9. 后台服务启动前台Service(跨进程)

    在开发中,很多时候我们会碰到在hmi里面做了页面布局,但是要求开机就显示. 我们的Service是开机自启动的,但是hmi不是开机自启动. 那么这个时候我们需要在hmi添加一个hmiService,用 ...

  10. Android如何降低service被杀死概率

    让app 的service常驻其实是很流氓的做法,但是需求摆在那里...  但是要清除一点:想百分百保活service在当前是无法做到的,只能降低service被杀死的概率,曾经看了多少篇网上大神的牛 ...

最新文章

  1. 聊一聊2020年实例分割领域的进展和未来展望
  2. 打开别人Xamarin项目找不到android.jar文件
  3. Java知识点总结(JavaIO- System类对IO的支持与Scanner类 )
  4. mysql如何处理图片吗_如何解决mysql插入图片后缀名问题?
  5. 用户注册功能交互流程
  6. 扎根中国20年,F5“代码到用户”线上峰会盛大启幕
  7. 用C语言编写绳索运动函数,福建省教师招聘考试小学数学真题试卷
  8. Study之2 Glance相关操作-devstack
  9. Wpf之MVVM线程问题
  10. python颜色识别_OpenCV(Python)学习之识别图片特定颜色
  11. 数据结构例程——串的模式匹配(Brute-Force算法)
  12. 如何重设或更改Verizon FIOS路由器的密码
  13. RoundedCorners
  14. python 拆分excel工作表_使用python拆分excel单元格方法
  15. 【信息系统项目管理师学习笔记】10大管理|47个过程组:项目整体管理|制定项目章程
  16. Maven插件列表_Maven插件查询_Maven插件查看
  17. “公式编辑器”的MT Extra字体无效,将无法显示和打印某些字符将。 请重新安装公式编辑器”,以便正确安装其字体。
  18. Mysql的基本操作和注意点
  19. 类设计者的核查表(转自C++rumination)
  20. 元素始终置于页面底部

热门文章

  1. Spring Boot工程结构推荐
  2. mysql数据库定时清理数据
  3. 鼠标不显示玩家服务器,远程链接服务器鼠标不显示
  4. adb 安装apk到指定设备
  5. 使用adb命令安装apk
  6. autojs读取文字_Auto.js 获取识别图片文本
  7. C盘根目录出现msdia80.dll解决办法
  8. 宏电GPRS DTU H7210调试报告(参数配置)
  9. Mac应用程序崩溃,无法启动的解决方法
  10. 哲学家就餐问题与python解决方案