高通Android 12/13冻结应用

最近开发SDK遇到冻结应用需求,于是简单记录下。总体而言比较简单,调用系统接口实现此功能。

涉及类与方法

IPackageManager .aidl #  * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.*/@UnsupportedAppUsagevoid setApplicationEnabledSetting(in String packageName, in int newState, int flags,int userId, String callingPackage);PackageManager.java # setApplicationEnabledSettingPackageManagerService.java  # setApplicationEnabledSetting # setEnabledSetting

1、IPackageManager.aidl

代码路径 /frameworks/base/core/java/android/content/pm/IPackageManager.aidl

/*** As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.*/@UnsupportedAppUsagevoid setApplicationEnabledSetting(in String packageName, in int newState, int flags,int userId, String callingPackage);

2、PackageManagerService.java

代码路径 /frameworks/base/core/java/android/content/pm/PackageManagerService.java

 @Overridepublic void setComponentEnabledSetting(ComponentName componentName,int newState, int flags, int userId) {if (!mUserManager.exists(userId)) return;setEnabledSetting(componentName.getPackageName(),componentName.getClassName(), newState, flags, userId, null);}private void setEnabledSetting(final String packageName, String className, int newState,final int flags, int userId, String callingPackage) {if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT|| newState == COMPONENT_ENABLED_STATE_ENABLED|| newState == COMPONENT_ENABLED_STATE_DISABLED|| newState == COMPONENT_ENABLED_STATE_DISABLED_USER|| newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {throw new IllegalArgumentException("Invalid new component state: "+ newState);}PackageSetting pkgSetting;final int callingUid = Binder.getCallingUid();final int permission;if (callingUid == Process.SYSTEM_UID) {permission = PackageManager.PERMISSION_GRANTED;} else {permission = mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);}enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,true /* checkShell */, "set enabled");final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);boolean sendNow = false;boolean isApp = (className == null);final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);String componentName = isApp ? packageName : className;ArrayList<String> components;// readersynchronized (mLock) {pkgSetting = mSettings.getPackageLPr(packageName);if (pkgSetting == null) {if (!isCallerInstantApp) {if (className == null) {throw new IllegalArgumentException("Unknown package: " + packageName);}throw new IllegalArgumentException("Unknown component: " + packageName + "/" + className);} else {// throw SecurityException to prevent leaking package informationthrow new SecurityException("Attempt to change component state; "+ "pid=" + Binder.getCallingPid()+ ", uid=" + callingUid+ (className == null? ", package=" + packageName: ", component=" + packageName + "/" + className));}}}// Limit who can change which appsif (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {// Don't allow apps that don't have permission to modify other appsfinal boolean filterApp;synchronized (mLock) {filterApp = (!allowedByPermission|| shouldFilterApplicationLocked(pkgSetting, callingUid, userId));}if (filterApp) {throw new SecurityException("Attempt to change component state; "+ "pid=" + Binder.getCallingPid()+ ", uid=" + callingUid+ (className == null? ", package=" + packageName: ", component=" + packageName + "/" + className));}// Don't allow changing protected packages.if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {throw new SecurityException("Cannot disable a protected package: " + packageName);}}// Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden// app details activityif (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)&& !allowedByPermission) {throw new SecurityException("Cannot disable a system-generated component");}synchronized (mLock) {if (callingUid == Process.SHELL_UID&& (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {// Shell can only change whole packages between ENABLED and DISABLED_USER states// unless it is a test package.int oldState = pkgSetting.getEnabled(userId);if (className == null&&(oldState == COMPONENT_ENABLED_STATE_DISABLED_USER|| oldState == COMPONENT_ENABLED_STATE_DEFAULT|| oldState == COMPONENT_ENABLED_STATE_ENABLED)&&(newState == COMPONENT_ENABLED_STATE_DISABLED_USER|| newState == COMPONENT_ENABLED_STATE_DEFAULT|| newState == COMPONENT_ENABLED_STATE_ENABLED)) {// ok} else {throw new SecurityException("Shell cannot change component state for " + packageName + "/"+ className + " to " + newState);}}}if (className == null) {// We're dealing with an application/package level state changesynchronized (mLock) {if (pkgSetting.getEnabled(userId) == newState) {// Nothing to doreturn;}}// If we're enabling a system stub, there's a little more work to do.// Prior to enabling the package, we need to decompress the APK(s) to the// data partition and then replace the version on the system partition.final AndroidPackage deletedPkg = pkgSetting.pkg;final boolean isSystemStub = (deletedPkg != null)&& deletedPkg.isStub()&& deletedPkg.isSystem();if (isSystemStub&& (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT|| newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {if (!enableCompressedPackage(deletedPkg, pkgSetting)) {return;}}if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT|| newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {// Don't care about who enables an app.callingPackage = null;}synchronized (mLock) {pkgSetting.setEnabled(newState, userId, callingPackage);if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER|| newState == COMPONENT_ENABLED_STATE_DISABLED)&& checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)== PERMISSION_GRANTED) {// This app should not generally be allowed to get disabled by the UI, but if it// ever does, we don't want to end up with some of the user's apps permanently// suspended.unsuspendForSuspendingPackage(packageName, userId);removeAllDistractingPackageRestrictions(userId);}}} else {synchronized (mLock) {// We're dealing with a component level state change// First, verify that this is a valid class name.AndroidPackage pkg = pkgSetting.pkg;if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {if (pkg != null &&pkg.getTargetSdkVersion() >=Build.VERSION_CODES.JELLY_BEAN) {throw new IllegalArgumentException("Component class " + className+ " does not exist in " + packageName);} else {Slog.w(TAG, "Failed setComponentEnabledSetting: component class "+ className + " does not exist in " + packageName);// Safetynet logging for b/240936919EventLog.writeEvent(0x534e4554, "240936919", callingUid);return;}}switch (newState) {case COMPONENT_ENABLED_STATE_ENABLED:if (!pkgSetting.enableComponentLPw(className, userId)) {return;}break;case COMPONENT_ENABLED_STATE_DISABLED:if (!pkgSetting.disableComponentLPw(className, userId)) {return;}break;case COMPONENT_ENABLED_STATE_DEFAULT:if (!pkgSetting.restoreComponentLPw(className, userId)) {return;}break;default:Slog.e(TAG, "Invalid new component state: " + newState);return;}}}synchronized (mLock) {if ((flags & PackageManager.SYNCHRONOUS) != 0) {flushPackageRestrictionsAsUserInternalLocked(userId);} else {scheduleWritePackageRestrictionsLocked(userId);}updateSequenceNumberLP(pkgSetting, new int[] { userId });final long callingId = Binder.clearCallingIdentity();try {updateInstantAppInstallerLocked(packageName);} finally {Binder.restoreCallingIdentity(callingId);}components = mPendingBroadcasts.get(userId, packageName);final boolean newPackage = components == null;if (newPackage) {components = new ArrayList<>();}if (!components.contains(componentName)) {components.add(componentName);}if ((flags&PackageManager.DONT_KILL_APP) == 0) {sendNow = true;// Purge entry from pending broadcast list if another one exists already// since we are sending one right away.mPendingBroadcasts.remove(userId, packageName);} else {if (newPackage) {mPendingBroadcasts.put(userId, packageName, components);}if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {// Schedule a message - if it has been a "reasonably long time" since the// service started, send the broadcast with a delay of one second to avoid// delayed reactions from the receiver, else keep the default ten second delay// to avoid extreme thrashing on service startup.final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay? BROADCAST_DELAY: BROADCAST_DELAY_DURING_STARTUP;mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);}}}final long callingId = Binder.clearCallingIdentity();try {if (sendNow) {int packageUid = UserHandle.getUid(userId, pkgSetting.appId);sendPackageChangedBroadcast(packageName,(flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);}} finally {Binder.restoreCallingIdentity(callingId);}}

3、PackageManager.java 

代码路径 /frameworks/base/core/java/android/content/pm/PackageManager.java

     * Set the enabled setting for an application* This setting will override any enabled state which may have been set by the application in* its manifest.  It also overrides the enabled state set in the manifest for any of the* application's components.  It does not override any enabled state set by* {@link #setComponentEnabledSetting} for any of the application's components.** @param packageName The package name of the application to enable* @param newState The new enabled state for the application.* @param flags Optional behavior flags.*/@RequiresPermission(value = android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE,conditional = true)public abstract void setApplicationEnabledSetting(@NonNull String packageName,@EnabledState int newState, @EnabledFlags int flags);

4、代码调用 示例 packageName就是当前需要冻结应用包名 冻结标志位PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER                                            

IPackageManager iPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
iPackageManager.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLE, 0, 0, "shell:" + android.os.Process.myUid());

5、测试之后在Settings里面查看冻结应用是否显示停用,如果是表面冻结应用成功。解冻也是类似只是设置标志位不一样, PackageManager.COMPONENT_ENABLED_STATE_ENABLED

try {IPackageManager iPackageManager = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));if (iPackageManager != null) {iPackageManager.setApplicationEnabledSetting(packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,0, 0, "shell:" + android.os.Process.myUid());Log.e("unfreezeApp", "freeze PackageName=" + packageName);}} catch (RemoteException e) {Log.e("unfreezeApp", "freeze PackageManager RemoteException=" + e.getMessage());}

到这里基本结束了。转载请注册出处高通Android 12/13冻结应用-CSDN博客,谢谢!

补充标志位状态值

COMPONENT_ENABLED_STATE_DEFAULT, //启用APP或组件,忽略manifest的定义。 COMPONENT_ENABLED_STATE_ENABLED, //禁用APP或组件,忽略manifest的定义。 COMPONENT_ENABLED_STATE_DISABLED, //以用户身份禁用APP,忽略manifest的定义。不能用于组件操作。 COMPONENT_ENABLED_STATE_DISABLED_USER, //禁用APP直到用户想用才出现。也就是说,正常情况下,用户看不到(比如在Launcher上);但是特殊情况下,用户还是能看到并选择到(比如输入法APP)。不能用于组件操作。 COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,

感谢 Android 获取所有被禁用或冷冻的应用信息_android获取被停用的应用-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

宝塔面板修改端口后无法登入

今天通过宝塔面板登录腾讯云主机&#xff0c;看到下面的提醒&#xff0c;顺便点进去随便改了个端口 本以为改端口是很简单事情&#xff0c;结果我改完之后面板立马登不上了&#xff0c;接下来我改了登录地址和端口也不行&#xff0c;我以为是防火墙的问题&#xff0c;增加了防火…

SpringBoot基于函数替换的热重载

背景 SpringBoot项目每次启动都很慢&#xff0c;有时候调试仅仅是改一点点东西&#xff0c;就要重启工作效率太低&#xff0c;希望能修改完代码&#xff0c;执行快捷键后就把该类的修改生效。&#xff08;仅限于Bean的修改生效&#xff09; 原理 SpringBoot的逻辑基本都是集…

ViT:1 从DETR说起

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提供了大模型领域最新技…

Pycharm在下载安装第三方库时速度慢或超时问题 / 切换国内镜像地址

pycharm下载第三方库速度极慢&#xff0c;搜索了一下&#xff0c;发现方法非常乱&#xff0c;稍作整理。这个问题一般都会出现&#xff0c;在我们开发中遇到的常见问题&#xff0c;根据以下解决方法&#xff0c;基本可以解决&#xff0c;但是不能100%保证 Installing packages …

打造一个增强版Kimi:可以生成图片、PPT、PDF文档、数据分析等

Kimi虽然在国内AI大模型中表现不错&#xff0c;但是和ChatGPT还是差不少功能。现在有一个很简单的方法&#xff0c;把kimi功能增强&#xff0c;使用效果大大改善&#xff0c;比如生成图片&#xff1a; 具体方法如下&#xff1a; 打开coze网站&#xff1a;https://www.coze.cn/…

Elementui里使用el-date-picker来选取指定时间段(时间段不超过31天)

需求描述&#xff1a; 1.禁止选择当前日期之后的所有日期2.选择的时间范围小于等于31天&#xff0c;其他日期禁用<el-date-picker v-model"historySubmitModel.historyDateTime" type"daterange" range-separator"- " start-placeholder"…

鸿蒙应用开发系列 篇四:鸿蒙系统应用开发基础

文章目录 系列文章概述ArkTS应用(Stage模型)示例应用示例代码使用模拟器运行应用使用真机运行应用应用程序包共享包应用配置文件(Stage模型)资源目录示例系列文章 鸿蒙应用开发系列 篇一:鸿蒙系统概述 鸿蒙应用开发系列 篇二:鸿蒙系统开发工具与环境

【c++基础】昆虫繁殖

说明 科学家在热带森林中发现了一种特殊的昆虫&#xff0c;这种昆虫的繁殖能力很强。每对成虫每过x个月产y对卵&#xff0c;每对卵要过两个月长成成虫。假设每个成虫不死&#xff0c;第一个月只有一对成虫&#xff0c;且卵长成成虫后的第一个月不产卵(过X个月产卵)&#xff0c…

C++容器之位集(std::bitset)

目录 1 概述2 使用实例3 接口使用3.1 constructor3.2 count_and_size3.3 test3.4 any3.5 none3.6 all3.7 set3.8 reset3.9 filp3.10 to_string3.11 to_ulong3.12 to_ullong3.13 operators1 概述 位集存储位(只有两个可能值的元素:0或1,true或false,…)。   该类模拟bool…

推荐一款自助分析的财务分析软件:奥威BI软件

奥威BI软件是一款支持多维度动态自助分析的软件&#xff0c;预设了智能财务分析方案&#xff0c;提供内存行列计算模型解决财务指标计算难题&#xff0c;界面简洁&#xff0c;以点击、拖曳操作为主&#xff0c;十分适合没有IT背景的财务人做财务分析。因此也经常有人说奥威BI软…

Spark搭建 Standalone模式详细步骤

Standalone模式概述&#xff1a; Standalone模式是Spark自带的一种集群模式&#xff08;本地集群&#xff0c;不依赖与外部集群&#xff0c;比如Yarn&#xff09;&#xff0c;可以真实地在多个机器之间搭建Spark集群的环境。 Standalone是完整的Spark运行环境,其中: Master角…

OpenFeign微服务调用组件使用

前言&#xff1a;OpenFeign是可以跨服务、跨进程的调用方式。 什么是Feign Feign是Netflix开发的声明式、模版化的HTTP客户端。 优势: Feign可以做到使用 HTTP 请求远程服务时就像调用本地方法一样的体验&#xff0c;开发者完全感知不到这是远程方法&#xff0c;更感知不到这…

【TB作品】stm32单片机读取DS2401程序

DS2401是由Analog Devices公司生产的一种硅序列号芯片&#xff0c;它提供了一个绝对唯一的64位ROM识别码&#xff0c;用于确保可追溯性。以下是对DS2401器件的分析&#xff1a; 特点和优势&#xff1a; 唯一性&#xff1a;每个DS2401芯片都有一个独一无二的64位注册码&#x…

PointPillars, CenterPoint,和TransFusion

PointPillars, CenterPoint, and TransFusion These models are primarily used for 3D object detection in autonomous driving. Here is a brief introduction to PointPillars, CenterPoint, and TransFusion: PointPillars 领域&#xff1a;计算机视觉&#xff0c;自动…

[less配置]vue2引入less

1、终端输入&#xff1a;npm install less less-loader --save-dev 2、在package.json查看是否安装less依赖 3、调用

vue2快速安装环境,从0-1创建vue2项目教程

vue2快速安装环境&#xff0c;从0-1创建vue2项目教程(windows) 一、node下载 1.如何查看node版本和npm版本 二、npm安装脚手架 1.注意事项 三、vue2选项解读 四、运行脚手架 一、node下载 1、(node.js中文网) 下载长期稳定版本就行 解释下node.js和npm的关系? 想象你在…

原始字面常量(C++11)

原始字面常量&#xff08;C11&#xff09; 文章目录 原始字面常量&#xff08;C11&#xff09;前言一、原始字面量二、代码示例总结 前言 字面量一般是指数值&#xff08;12、454等&#xff09;和字符串&#xff08;“Hw”、“h\t”&#xff09;&#xff0c;但是有时候我们想表…

leetcode题目274

H指数 中等 给你一个整数数组 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义&#xff1a;h 代表“高引用次数” &#xff0c;一名科研人员的 h 指数 是指他&#xff08;她&…

Android Studio 问题集锦

报 Plugin [id: ‘com.android.application’, version: ‘8.1.3’, apply: false] was not found in any of the following sources: 场景&#xff1a;在一个Android 11的项目中添加一个Android 9的项目作为其Module&#xff0c;结果导致原项目无法正常运行&#xff0c;且原项…

PyTorch安装与配置

前言 参考文档&#xff1a;https://github.com/TingsongYu/PyTorch-Tutorial-2nd 环境配置之Anaconda 解释器——python.exe&#xff0c;是人类与CPU之间的桥梁&#xff0c;需要配置系统环境变量 Anaconda&#xff1a;集成环境&#xff0c;包管理器 Conda 安装 Anaconda&am…