【android】通过 PackageManager 获得你想要的 App 信息

文章源自https://www.cnblogs.com/plokmju/p/7694110.html

一、前言

​ 有些场景下,我们会需要获取一些其它 App 的各项信息,例如:App 名称,包名、Icon 等。这个时候就需要使用到 PackageManager 这个类了。

​ 本篇就 PackageManager 的使用,做一个详尽的讲解,助你拿到各项 App 的信息,包括一些未安装的 App 的信息。

二、需要用到的类

​ 当我们需要获取到指定 App 的各项信息的时候,我们需用到 Android 的 相应Api。

​ 首先需要获取 PackageManager(以下简称 PM) 对象,通过 PM 对象,可以获取到我们需要的各项 App 的信息类。

​ 这里涉及到的 App 信息类包括:PackageInfo、ApplicationInfo、ActivityInfo、ServiceInfo、ProviderInfo 等,还有一个 ResolveInfo 类,它比较特殊一点,不和前面的结构为从属关系。

​ 这些类,都可以在根据 AndroidManifest.xml 中定义的组件进行划分,大概的结构如下。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q4fmxsf7-1608733122173)(.\image\packageInfo.jpg)]

​ 一个manifest包含一个package,用PackageInfo表示,一个 PackageInfo 对应一个 ApplicationInfo,而其中又包含若干个 ActivityInfo、ServiceInfo、ProviderInfo。

2.1PackageManager

​ PackageManager 是一个抽象类,我们一般操作的 PackageManager ,实际上是它的实现类 ApplicationPackageManager 这个对象。

​ 在 Context 中,就有获取 PM 对象的方法,getPackageManager(),所以四大组件想要获取它是非常简单的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2mAk2Ib-1608733122175)(.\image\pakageManage.jpg)]

​ PM 中,提供了非常多的方法,供我们通过不同的条件,获取到 PackageInfo 对象、ApplicationInfo 对象等,它是本文的基础。

2.2PackageInfo

​ PackageInfo 从名称上也可以看出来,它主要用于存储获取到的 Package 的一些信息,包括:包名(packageName)、版本号(versionCode)、版本名(versionName)。

​ 基本上拿到了 PackageInfo ,你就可以拿到大部分此 Apk 相关的信息了。并且,PackageInfo 中有一个 applicationInfo 的字段,是可以直接获取到与它相关的 ApplicationInfo 对象的。

这里介绍几个 PackageInfo 中,比较常用的字段:

  • packageName:包名。
  • versionCode:版本号
  • versionName:版本名。
  • firstInstallTime:首次安装时间。
  • lastUpdateTime:最后一次覆盖安装时间。

2.3 ApplicationInfo

ApplicationInfo 相对于 PackageInfo 用的会比较少一些。它主要用于获取 Apk 定义在 AndroidManifest.xml 中的一些信息。

这里介绍几个比价常用的:

  • packageName:包名
  • targetSdkVersion:目标 SDK 版本。
  • minSdkVersion:最小支持 SDK 版本,有 Api 限制,最低在 Api Level 24 及以上支持。
  • sourceDir:App 的 Apk 源文件存放的目录。
  • dataDir:data 目录的全路径。
  • metaData:Manifest 中定义的 meta 标签数据。
  • uid:当前 App 分配的 uid。

可以看到 ApplicationInfo 涵盖的信息,基本上都是在 AndroidManifest.xml 中定义的信息,并且有一些属性是有 Api Level 限制的,所以不确定的属性,提前看一下文档,确定是否全版本支持。

2.4 ActivityInfo

​ ActivityInfo、ServiceInfo、ProviderInfo 这三个是平级的,熟悉的一眼就能看出来,它们就是 Android 定义的四大组件中的几个。各自涵盖了一部分信息。一般在外部获取其他 App 的信息的时候,不会获取到这么细致的数据,如果有,看看这几个类准没错。

那么就不再费时去介绍它们了。

三、基本操作

​ 到现在基本上就已经了解到在当前设备上获取到 Apk 信息的各项类了,接着来看看具体如何使用 PM。

3.1 获取所有安装的 App

​ 如果想要获取当前设备上已经安装的所有 App,可以使用 getInstalledPackages() 方法获取到它所有的已安装 App 的 PackageInfo 。

    /**
     * 获取当前设备上安装的所有App
     */
    public List<PackageInfo> getAllApp(Context context){
        PackageManager pm = context.getPackageManager();
        List<PackageInfo>  packageInfos = pm.getInstalledPackages(PackageManager.GET_ACTIVITIES);
        return packageInfos;
    }

​ PackageManager 中,很多方法都会需要传递一个 flags 的字段,它表示你当前需要获取到的 App 的信息。取值范围有挺多的,获取不同的信息使用不同的 Flags,通常如果没有额外的要求,直接使用 GET_ACTIVITYS 即可。

3.2 判断 App 是否安装

​ 这里主要说的是通过包名,判断 App 是否安装在当前设备上。最简单的逻辑就是去获取 PackageInfo ,如果能拿回来数据,就说明是有安装的。

    /**
     * 判断 App 是否安装
     */
    public boolean isInstalled (Context context,String packageName){
        if(packageName == null || packageName.length() < 1){
            return false;
        }
        PackageManager pm = context.getPackageManager();
        try{
            PackageInfo packageInfo = pm.getPackageInfo(packageName,PackageManager.GET_ACTIVITIES)
            return packageInfo != null;
        }catch(Throwable ignore){

        }

        return false;
    }

3.3 通过包名获取PackageInfo

​ 其实前面判断 App 是否安装的时候,就已经获取到了 PackageInfo 信息,这里只需要将它返回出去即可。

    /**
     * 根据包名获取 PackageInfo
     */
    public PackageInfo getPackageInfo (Context context,String packageName){
        if(packageName == null || packageName.length() < 1){
            return null;
        }
        PackageManager pm = context.getPackageManager();
        try{
            PackageInfo packageInfo = pm.getPackageInfo(packageName,PackageManager.GET_ACTIVITIES)
            return packageInfo ;
        }catch(Throwable ignore){

        }

        return null;
    }

3.4 获取版本号和版本名

​ 这里只需要根据 PackageInfo 中的字段,获取到对应的值就好了。

/**
* 根据包名获取 版本号
*/
public int getPackageVersionCode (Context context,String packageName){
    PackageInfo packageInfo = getPackageInfo (context, packageName);
    if(packageName != null){
        return packageInfo.versionCode;
    }
    
    return-1;
}

    /**
     * 根据包名获取 版本名
     */
    public String getPackageVersionName (Context context,String packageName){
        PackageInfo packageInfo = getPackageInfo (context, packageName);
        if(packageName != null){
            return packageInfo.versionName;
        }

        return null;
    }

3.5 获取 App 的名称

​ 获取 App 的名称,就需要用到 ApplicationInfo 这个对象了,其中 loadLabel() 方法返回的,就是 App 的名称,因为Manifest中label就是现实的App名称。

    /**
     * 获取 App名
     */
    public String getApplicationLabel (Context context,String packageName){
        if(packageName == null || packageName.length() < 1){
            return null;
        }
        PackageManager pm = context.getPackageManager();
        PackageInfo packeInfo = getPackageInfo (context, packageName);
        if(packageInfo != null){
            return packageInfo.applicationInfo.loadLabel(pm).toString();
        }
        return null;
    }

3.6 获取 App 的 Icon

​ 在 ApplicationInfo 中,还可以通过 loadIcon() 获取到 App 的 Icon。它返回的是一个 Drawable 对象,可以直接使用。

    /**
     * 获取 App的 icon
     */
    public Drawable getApplicationIcon (Context context, String packageName){
        if(packageName == null || packageName.length()< 1){
            return null;
        }
        PackageManager pm = context.getPackageManager();
        PackageInfo packageInfo = getPackageInfo (context, packageName);
        if(packageInfo != null){
            return packageInfo.applicationInfo.loadIcon(pm);
        }
        return null;
    }

3.7 根据Apk 文件,获取 PackageInfo

​ 前面介绍的方法,都是基于一个已安装的 App 的包名,来获取额外的信息。

​ 但是有时候,我们只有一个未安装的 Apk 文件,想要解析出 Apk 文件中的额外信息,PM 中,也有对应的 Api。非常的方便,直接使用 getPackageArchiveInfo() 即可。

    /**
     * 通过Apk路径,获取Apk信息
     */
    public PackageInfo getPackageArchiveInfo (Context context, String apkPath){
        try{
            PackageManager pm = context.getPackageManager();
            PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath,PackageManager.GET_ACTIVITIES);
            return packageInfo;
        }catch(Throwable ignore){
            return null;
        }
    }

​ 只要拿到这个 Apk 文件相关的 PackageInfo 信息,就有办法拿到其他的名称、icon 、版本号、版本名、包名等信息。和前面介绍的例子类似,这里就不再一一列举了。

整体来说,到这里已经讲解清楚如何使用 PM 获取 App 的基本信息。

但是并不包含 App 在运行时的一些内存的情况,哪些数据你想获取,单单依靠 PackageManager 是做不到的,就不再这里展开说了,有机会再详细说明一下。

String archiveFilePath="sdcard/download/Law.apk";//安装包路径
        PackageManager pm = getPackageManager();  
        PackageInfo info = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES);  
  if(info != null){  
   ApplicationInfo appInfo = info.applicationInfo;  
            String appName = pm.getApplicationLabel(appInfo).toString();  
                String packageName = appInfo.packageName; //得到安装包名称
            String version=info.versionName;          //得到版本信息     
            Toast.makeText(test4.this, "packageName:"+packageName+";version:"+version, Toast.LENGTH_LONG).show();
            Drawable icon = pm.getApplicationIcon(appInfo);//得到图标信息
            TextView tv = (TextView)findViewById(R.id.tv); //显示图标
            tv.setBackgroundDrawable(icon);
        }

​ 还有就是,PM 中,很多方法,都是有可能触发 『Package manager has died』这个 RuntimeException 的,其实就是很多个线程在频繁调用。如果想要避免,加锁加缓存即可。具体的情况,参考文章《PackageManager可以乱用吗?》https://mp.weixin.qq.com/s?__biz=MzIxNjc0ODExMA==&mid=2247484104&idx=1&sn=4082bc400d6784c5e07e3779bde662f4&chksm=97851be9a0f292ffb1a1c770dd027a3460ae49d3a2b34875ed0a72ce7d7118288cfa28dd6ee0#rd。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android系统中的PackageManager(包管理器)是一个系统级别的服务,它是一个应用程序包的管理器,可以用来安装、卸载、查询应用程序包信息等操作。PackageManager API是Android系统中非常重要的一个API,它可以让开发者获取应用程序包的信息,比如版本号、权限等等。 常用的PackageManager命令有: 1. 查询已安装应用的信息 ``` pm list packages // 列出所有已安装的应用的包名 pm list packages -s // 列出所有已安装的系统应用的包名 pm list packages -3 // 列出所有已安装的第三方应用的包名 pm list packages -f // 列出所有已安装应用的APK路径 pm list packages -d // 只列出已禁用的应用 pm list packages -e // 只列出系统已启用的应用 ``` 2. 安装应用 ``` pm install /path/to/app.apk // 安装应用 pm install -r /path/to/app.apk // 重新安装应用,保留应用数据 pm install -t /path/to/app.apk // 允许安装覆盖其他应用 pm install -i <installer_package_name> /path/to/app.apk // 指定应用安装包的安装来源 ``` 3. 卸载应用 ``` pm uninstall com.package.name // 卸载应用 pm uninstall -k com.package.name // 卸载应用,保留应用数据和缓存 ``` 4. 查询应用信息 ``` pm dump com.package.name // 输出应用信息 pm path com.package.name // 输出应用APK路径 pm list features // 列出系统支持的特性 pm list instrumentation // 列出所有已安装的Instrumentation ``` 5. 其他命令 ``` pm enable com.package.name // 启用应用 pm disable com.package.name // 禁用应用 pm clear com.package.name // 清除应用数据和缓存 ``` 以上是一些常用的PackageManager命令,使用时需要注意权限问题,部分命令需要root权限才能执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值