Android-Framework pm list packages和pm install返回指定应用信息
一、环境
高通 Android 13
注:Android10 和Android13有些差异,代码位置不变,参照修改即可
二、pm简单介绍
pm工具为包管理(package manager)的简称
可以使用pm工具来执行应用的安装和查询应用宝的信息、系统权限、控制应用
pm工具是Android开发与测试过程中必不可少的工具,shell命令格式如下:
pm <command>
kona:/ # which pm
/system/bin/pm
kona:/ #
kona:/ # file system/bin/pm
system/bin/pm: /system/bin/sh script
三、pm命令对应的源码位置如下
frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
这里通过修改源码,达到以下两个效果:
1、pm list packages -3 返回详细应用信息;2、pm install 返回包名和启动Activity
源码修改:
@@ -145,6 +145,11 @@ import java.util.concurrent.CountDownLatch;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;+import android.app.usage.StorageStats;
+import android.app.usage.StorageStatsManager;
+import java.util.UUID;
+import java.util.HashSet;
+class PackageManagerShellCommand extends ShellCommand {/** Path for streaming APK content */private static final String STDIN_PATH = "-";
@@ -623,6 +628,7 @@ class PackageManagerShellCommand extends ShellCommand {null /* splitApkPaths */, null /* splitRevisionCodes */,apkLite.getTargetSdkVersion(), null /* requiredSplitTypes */,null /* splitTypes */);
+ params.sessionParams.setAppPackageName(pkgLite.getPackageName());sessionSize += InstallLocationUtils.calculateInstalledSize(pkgLite,params.sessionParams.abiOverride, fd.getFileDescriptor());} catch (IOException e) {
@@ -842,7 +848,7 @@ class PackageManagerShellCommand extends ShellCommand {}private int runListPackages(boolean showSourceDir, boolean showSdks) throws RemoteException {
- final String prefix = showSdks ? "sdk:" : "package:";
+ final String prefix = showSdks ? "sdk:" : "PackageName:";final PrintWriter pw = getOutPrintWriter();int getFlags = 0;boolean listDisabled = false, listEnabled = false;
@@ -985,7 +991,7 @@ class PackageManagerShellCommand extends ShellCommand {stringBuilder.append(info.applicationInfo.sourceDir);stringBuilder.append("=");}
- stringBuilder.append(name);
+ stringBuilder.append(name+ ";");if (showVersionCode) {stringBuilder.append(" versionCode:");if (info.applicationInfo != null) {
@@ -998,6 +1004,47 @@ class PackageManagerShellCommand extends ShellCommand {stringBuilder.append(" installer=");stringBuilder.append(mInterface.getInstallerPackageName(info.packageName));}
+
+
+
+ if (listThirdParty) {
+ stringBuilder.append(" Activity:");
+ stringBuilder.append(getClassName(info.packageName) + ";");
+
+ stringBuilder.append(" Label:");
+ stringBuilder.append(mContext.getPackageManager().getApplicationLabel(info.applicationInfo) + ";");
+
+ //app size
+ String sourceDir = info.applicationInfo.sourceDir;
+ StorageStatsManager storageStatsManager = (StorageStatsManager) mContext.getSystemService(Context.STORAGE_STATS_SERVICE);
+ StorageManager storageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ StorageStats storageStats =null;
+ try{
+ UUID uuid = storageManager.getUuidForPath(new File(sourceDir));
+ storageStats = storageStatsManager.queryStatsForPackage(uuid, info.packageName,UserHandle.getUserHandleForUid(info.applicationInfo.uid));
+ }catch(IOException e){
+ e.printStackTrace();
+ }catch(NameNotFoundException e){
+ e.printStackTrace();
+ }
+ if(storageStats != null) {
+ long appSize = storageStats.getAppBytes() + storageStats.getCacheBytes() + storageStats.getDataBytes();
+
+ stringBuilder.append(" Size:");
+ stringBuilder.append(appSize + ";");
+ }
+
+ //version name
+ stringBuilder.append(" VersionName:");
+ stringBuilder.append(info.versionName + ";");
+
+ //Uid
+ stringBuilder.append(" Uid:");
+ stringBuilder.append( info.applicationInfo.uid + ";");
+
+ }
+
+List<String> uids = out.computeIfAbsent(stringBuilder.toString(), k -> new ArrayList<>());
@@ -1006,6 +1053,7 @@ class PackageManagerShellCommand extends ShellCommand {}}}
+for (Map.Entry<String, List<String>> entry : out.entrySet()) {pw.print(entry.getKey());List<String> uids = entry.getValue();
@@ -1018,6 +1066,58 @@ class PackageManagerShellCommand extends ShellCommand {return 0;}+
+ private String getClassName(String packageName){
+ try {
+ Intent intent = new Intent();
+ Intent baseIntent = intent;
+
+ baseIntent = new Intent(Intent.ACTION_MAIN);
+ baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ baseIntent.setPackage(packageName);
+
+ if (baseIntent != null) {
+ Bundle extras = intent.getExtras();
+ intent.replaceExtras((Bundle) null);
+ Bundle uriExtras = baseIntent.getExtras();
+ baseIntent.replaceExtras((Bundle) null);
+ if (intent.getAction() != null && baseIntent.getCategories() != null) {
+ HashSet<String> cats = new HashSet<String>(baseIntent.getCategories());
+ for (String c : cats) {
+ baseIntent.removeCategory(c);
+ }
+ }
+ intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
+ if (extras == null) {
+ extras = uriExtras;
+ } else if (uriExtras != null) {
+ uriExtras.putAll(extras);
+ extras = uriExtras;
+ }
+ intent.replaceExtras(extras);
+ }
+
+ mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), mTargetUser, false, false, null, null);
+
+ ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
+ mTargetUser);
+ if(ri != null && ri.activityInfo.name != null){
+ return ri.activityInfo.name;
+ }else{
+ return "NULL";
+ }
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed calling service", e);
+ } catch (Exception e){
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+
+
+
+private int runListPermissionGroups() throws RemoteException {final PrintWriter pw = getOutPrintWriter();final List<PermissionGroupInfo> pgs = mPermissionManager.getAllPermissionGroups(0);
@@ -1464,6 +1564,14 @@ class PackageManagerShellCommand extends ShellCommand {}abandonSession = false;//pm install 时,返回指定格式
+ if (params.sessionParams.appPackageName != null) {
+ if (getClassName(params.sessionParams.appPackageName) != null){
+ pw.print(params.sessionParams.appPackageName);
+ pw.println("/" + getClassName(params.sessionParams.appPackageName));
+ }
+ }
+
+if (params.sessionParams.isStaged && params.stagedReadyTimeoutMs > 0) {return doWaitForStagedSessionReady(sessionId, params.stagedReadyTimeoutMs, pw);}
相关文章:
Android-Framework pm list packages和pm install返回指定应用信息
一、环境 高通 Android 13 注:Android10 和Android13有些差异,代码位置不变,参照修改即可 二、pm简单介绍 pm工具为包管理(package manager)的简称 可以使用pm工具来执行应用的安装和查询应用宝的信息、系统权限、…...
CSS
什么是CSS? CSS是一门语言,用于控制网页表现 CSS(Cascading Style Sheet):层叠样式表 W3C标准:网页主要由三部分组成 结构:HTML表现:CSS行为:JavaScript CSS导入方式…...
算法详解——选择排序和冒泡排序
一、选择排序 选择排序算法的执行过程是这样的:首先,算法遍历整个列表以确定最小的元素,接着,这个最小的元素被置换到列表的开头,确保它被放置在其应有的有序位置上。接下来,从列表的第二个元素开始&#x…...
图论(蓝桥杯 C++ 题目 代码 注解)
目录 迪杰斯特拉模板(用来求一个点出发到其它点的最短距离): 克鲁斯卡尔模板(用来求最小生成树): 题目一(蓝桥王国): 题目二(随机数据下的最短路径&#…...
矩阵起源新一年喜报连连!
新春伊始 矩阵起源向大家分享 一连串好消息 首先,公司创始人兼CEO王龙先生获评“2023深圳创新突出贡献人物“。这一荣誉是对其在推动数据库行业技术创新和产品开发方面所做出的卓越贡献的认可。他的领导力和创新精神不仅引领我司取得了显著的成就,也为…...
牛客——紫魔法师(并查集)
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 “サーヴァント、キャスター、Medea。”--紫魔法师 给出一棵仙人掌(每条边最多被包含于一个环,无自环,无重边,保证连通),要求用最少的…...
最新WooCommerce教程指南-如何搭建B2C外贸独立站
WooCommerce是全球最受欢迎的开源电子商务平台之一。它基于WordPress建站,只需一键安装即可使用。该平台提供了丰富的功能,包括产品发布、库存管理、支付网关和运输发货等,可以帮助搭建各种类型的电子商务网站。相比其他竞争对手,…...
一文教会你SpringBoot是如何启动的
SpringBoot启动流程分析 流程图 源码剖析 运行Application.run()方法 我们在创建好一个 SpringBoot 程序之后,肯定会包含一个类:xxxApplication,我们也是通过这个类来启动我们的程序的(梦开始的地方),而…...
车载测试面试:各大车企面试题汇总
本博主可协助大家成功进军车载测试行业 TBOX 深圳 涉及过T-BOX测试吗Ota升级涉及的台架环境是什么样的?上车实测之前有没有一个仿真环境台架环境都什么零部件T-BOX了解多少Linux和shell有接触吗 单片机uds诊断是在实车上座的吗 uds在实车上插的那口 诊断仪器是哪…...
Qt散文一
Qt的事件分为普通事件和系统事件,普通事件比如用户按下键盘,系统事件比如定时器事件。事件循环的开始是从main函数的QApplication,然后调用exec()开始的,在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件…...
MySQL学习Day32——数据库备份与恢复
在任何数据库环境中,总会有不确定的意外情况发生,比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的,这些情况可能会导致数据的丢失、 服务器瘫痪等严重的后果。存在多个服务器时,会出现主从服…...
阅读基础知识
一 网络 1. 三次握手四次挥手 三次握手:为了建立长链接进行交互即建立一个会话,使用 http/https 协议 ① 客户端产生初始化序列号 Seqx ,向服务端发送建立连接的请求报文,将 SYN1 同步序列号; ② 服务端接收建立连接…...
【NestJS 编程艺术】1. NestJS设计模式深度解析:构建高效、可维护的服务端应用
在当今快速发展的软件开发领域,Node.js凭借其轻量级和高性能的特点,已经成为了构建服务端应用的首选技术之一。然而,随着应用规模的扩大,传统的Node.js框架如Express和Koa可能在架构设计和代码组织上显得力不从心。这时࿰…...
QT中connect()的参数5:Qt::DirectConnection、Qt::QueuedConnection区别
原文链接:https://blog.csdn.net/Dasis/article/details/120916993 connect用于连接QT的信号和槽,在qt编程过程中不可或缺。它其实有第5个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。 Qt::AutoConnect…...
VXLAN学习笔记
声明:该博客内容大部分参考参考链接整理 什么是VXLAN? VXLAN(Virtual Extensible LAN)即虚拟扩展局域网,是大二层网络中广泛使用的网络虚拟化技术。在源网络设备与目的网络设备之间建立一条逻辑VXLAN隧道,采用MAC in UDP的封装方…...
全排列的不同写法(茴字的不同写法)及对应的时间开销
资源课件: CS106B-recursion-pptstanford library-timer.hstanford library-set.h 不同的方法 1------ Set<string> permutations1Rec(string remaining) {Set<string> res;if(remaining.size() 0) {res "";}else {for(int i 0; i <…...
权衡后台数据库设计中是否使用外键
目录 引言 外键简介 对比 真实后台项目中的权衡 结论 引言 在大学学习数据库课程时,我们会早早的接触到外键这一概念,同时我相信大部分人在懂了外键的概念后都会觉得外键很重要,在涉及多表一定要用,但后来在我接触到真实项目…...
ChatGPT提示词方法的原理
关于提示词,我之前的一些文章可以参考: 【AIGC】AI作图最全提示词prompt集合(收藏级)https://giszz.blog.csdn.net/article/details/134815245?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9ibG9nL21hbmFnZS9hcnRpY2xlP3NwbT0xMDExL…...
计算机网络 谢希仁(001-1)
计算机网络-方老师 总时长 24:45:00 共50个视频,6个模块 此文章包含1.1到1.4的内容 简介 1.1计算机网络的作用 三网融合(三网合一) 模拟信号就是连续信号 数字信号是离散信号 1.2互联网概述 以前2兆带宽就要98 现在几百兆带宽也就几百块 …...
Windows,MacOS,Linux下载python并配置环境图文讲解
Windows 打开python官网 点击download 点击黄色按钮 另存为 打开文件 全选 配置安装路径 安装中 关闭路径长度限制 完成 验证 同时按住winr(win就是空格键左边的东西) 输入cmd 键入python,如果出现版本(红框)即安装成功 MacOS 同理打开python官网 点击最新版本 拖…...
告别卡顿等待:HiveWE魔兽争霸III地图编辑器完全指南
告别卡顿等待:HiveWE魔兽争霸III地图编辑器完全指南 【免费下载链接】HiveWE A Warcraft III world editor. 项目地址: https://gitcode.com/gh_mirrors/hi/HiveWE 还在为魔兽争霸III原版地图编辑器的缓慢加载和复杂操作而烦恼吗?HiveWE是一款专注…...
如何5分钟完成HS2-HF_Patch安装:Honey Select 2汉化优化补丁终极指南
如何5分钟完成HS2-HF_Patch安装:Honey Select 2汉化优化补丁终极指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch HS2-HF_Patch是一款专为《Hone…...
电信数智版Wireshark 3.7.1:深度支持TLCP与国密算法的协议分析利器
1. 为什么国密协议分析不能只靠“标准Wireshark”——从一次TLCP握手失败说起去年底帮某政务云平台做等保三级复测时,客户网络里跑着一套自研的国密SSL网关,所有前端HTTPS流量都经它转换为TLCP协议(Transport Layer Cryptography Protocol&am…...
揭秘Gemini真实生命周期曲线:Gartner未公开的18个月LTV拐点图谱及3种续命策略(含SLA重谈判话术)
更多请点击: https://kaifayun.com 第一章:Gemini生命周期价值分析 Gemini 作为 Google 推出的多模态大模型系列,其生命周期价值不仅体现在推理性能与响应速度上,更贯穿于模型训练、部署、监控、迭代与退役的全链路环节。理解其生…...
PPTX转HTML终极指南:如何在浏览器中免费快速完成转换?
PPTX转HTML终极指南:如何在浏览器中免费快速完成转换? 【免费下载链接】PPTX2HTML Convert pptx file to HTML by using pure javascript 项目地址: https://gitcode.com/gh_mirrors/pp/PPTX2HTML 你是否经常需要将PowerPoint演示文稿转换为网页格…...
从AUC稳健下界到量子场论:机器学习与物理的数学统一
1. 项目概述:当机器学习遇见量子场论如果你在机器学习领域待过一段时间,对AUC(Area Under the ROC Curve)这个指标一定不陌生。它是衡量二分类模型性能的黄金标准,一个完美的分类器AUC为1,随机猜测则为0.5。…...
机器学习模型评估避坑指南:过调优与数据泄露的识别与防范
1. 项目概述与核心问题界定在机器学习项目的落地过程中,超参数调优几乎是每个从业者都会经历的环节。我们花费大量时间,尝试各种搜索策略——从网格搜索到贝叶斯优化,目标很明确:让模型在验证集上的指标再好看那么一点点。然而&am…...
熬夜赶论文效率低到哭?学长安利这几个AI论文写作软件
熬夜赶论文效率低到哭?选题没思路、大纲难搭建、初稿写不顺、文献找不全、润色没方向、降重费时间、格式不规范——这些论文写作的痛点,其实都可以通过用对AI工具、走对流程来解决。资深教授普遍推荐:千笔AI(中文全流程首选&#…...
如何快速获取网盘直链:LinkSwift 下载助手配置指南
如何快速获取网盘直链:LinkSwift 下载助手配置指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘…...
避开这些坑,你的孟德尔随机化分析结果才可靠:以口腔癌研究为例的实操避雷指南
孟德尔随机化分析实战避坑指南:从数据陷阱到稳健结论当你在深夜盯着屏幕上那个意义不明的0.6940093乘数,或是当MR-PRESSO分析结果始终无法收敛时,是否怀疑过自己的分析流程存在致命缺陷?孟德尔随机化(MR)作…...
