Android获取程序信息

我们知道程序信息存储在Androidmanifest.xml文件中

SDK提供了PackageInfo类,该类包含了从Androidmanifest.xml文件中收集的所有信息。

查看PackageInfo源码

//PackageInfo进行了序列化,可在进程间传递
public class PackageInfo implements Parcelable {

    //程序包名
    public String packageName;

    //版本名
    public String versionName;

    //版本号
    public int versionCode;

    //共享用户ID,签名相同的情况下程序之间数据共享
    public String sharedUserId;

    //安装时间,忽略之前安装后卸载情况,单位ms
    public long firstInstallTime

    //最后更新时间,单位ms,经验证版本号相同的APK覆盖安装,该值也是会发生变化的
    public long lastUpdateTime

    //请求的权限
    public String[] requestedPermissions;

    //<Application .../>中的信息,程序名,icon等
    public ApplicationInfo applicationInfo;

    //注册的Activity
    public ActivityInfo[] activities;

    //注册的广播
    public ActivityInfo[] receivers;

    //注册的服务
    public ServiceInfo[] services;

    //注册的Contentprovider
    public ProviderInfo[] providers;

}

PackageInfo的子类ApplicationInfo中封装了:
程序名称
程序图标等信息
如何获取这些信息的呢?
查看ApplicationInfo源码

//ApplicationInfo类的继承关系,进行了序列化,可在进程间传递
public class ApplicationInfo extends PackageItemInfo implements Parcelable {
    //ApplicationInfo类中的属性
    public int flags = 0;

    //判断是否是系统程序用到的常量,这里为什么用<<(逻辑左移)没搞明白,计算后的值十进制还是1
    public static final int FLAG_SYSTEM = 1<<0;
    /**判断是否是系统程序计算方法,
    (flags & ApplicationInfo.FLAG_SYSTEM) != 0表示是系统程序*/
}

ApplicationInfo继承PackageItemInfo类。
查看PackageItemInfo源码

//具体实现方法封装在父类PackageItemInfo类中
public class PackageItemInfo {

    //获取程序名称
    public CharSequence loadLabel(PackageManager pm);

    //获取程序图标
    public Drawable loadIcon(PackageManager pm);

}

知道了程序信息封装在PackageInfo类中。如何获取PackageInfo对象?
SDK提供了包管理类PackageManager,负责获取PackageInfo对象的。
查看PackageManager源码

public abstract class PackageManager {//是一个抽象类

    /**以下都是抽象方法*/
    //第一个参数:包名 ;第二个参数:为附加条件选项(如:GET_CONFIGURATIONS获取配置)
    PackageInfo getPackageInfo(String packageName, int flags);

    //获取已安装程序信息对象的列表
    List<PackageInfo> getInstalledPackages(int flags);

    //根据程序申请的权限过滤,申请某些特定权限的程序
    List<PackageInfo> getPackagesHoldingPermissions(String[] permissions,
     int flags);

    List<PackageInfo> getPreferredPackages(int flags);

    //获取程序大小,遗憾是@hide方法,只能通过反射机制调用
    void getPackageSizeInfo(String packageName, IPackageStatsObserver observer);

}

获取程序大小请移步到另一篇文章,详细讲解获取程序大小

具体实现,这篇文章不去详细讲解。
我们需要追踪到哪个类中可获取该对象实例即可,查看源码,
ContextWrapper类中提供获取PackageManager对象的函数

//ContextWrapper类中getPackageManager函数可获取到PackageManager对象
public class ContextWrapper extends Context {

    public PackageManager getPackageManager()  {   
          return mBase.getPackageManager();
    }
}

ContextWrapper类的子类

//从以下继承关系可以知道这些对象都可直接调用getPackageManager方法得到PackageManager对象

class Application extends ContextWrapper;

class ContextThemeWrapper extends ContextWrapper;

class Activity extends ContextThemeWrapper;

//Service为抽象类,需要实现Service调用getPackageManager方法获取PackageManager对象

public abstract class Service extends ContextWrapper;

开发中常遇到以下两种情形:

  • 1知道包名,获取该程序的信息
  • 2获取已安装的程序信息

获取包管理类PackageManager

// Application Activity Service中都可直接调用getPackageManager()方法获取PackageManager
PackageManager pm ;

 pm= Application.getPackageManager();

 pm = Activity.getPackageManager();

 pm = Service.getPackageManager();

包管理对象获取程序信息

// 知道包名,获取该程序信息
PackageInfo pi = pm.getPackageInfo(packageName,PackageManager.GET_CONFIGURATIONS);

//获取设备上安装的程序信息
//PackageManager.GET_UNINSTALLED_PACKAGES常量代表已经卸载的也会收集到
List<PackageInfo> apps;
apps = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);

获取到PackageInfo对象,任务完成,获取你想要的数据吧。

    原文作者:IT枫
    原文地址: https://www.jianshu.com/p/d088a042bf6d
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞