我們知道程序信息存儲(chǔ)在Androidmanifest.xml文件中
SDK提供了PackageInfo類,該類包含了從Androidmanifest.xml文件中收集的所有信息。
查看PackageInfo源碼
//PackageInfo進(jìn)行了序列化,可在進(jìn)程間傳遞
public class PackageInfo implements Parcelable {
//程序包名
public String packageName;
//版本名
public String versionName;
//版本號(hào)
public int versionCode;
//共享用戶ID,簽名相同的情況下程序之間數(shù)據(jù)共享
public String sharedUserId;
//安裝時(shí)間,忽略之前安裝后卸載情況,單位ms
public long firstInstallTime
//最后更新時(shí)間,單位ms,經(jīng)驗(yàn)證版本號(hào)相同的APK覆蓋安裝,該值也是會(huì)發(fā)生變化的
public long lastUpdateTime
//請(qǐng)求的權(quán)限
public String[] requestedPermissions;
//<Application .../>中的信息,程序名,icon等
public ApplicationInfo applicationInfo;
//注冊(cè)的Activity
public ActivityInfo[] activities;
//注冊(cè)的廣播
public ActivityInfo[] receivers;
//注冊(cè)的服務(wù)
public ServiceInfo[] services;
//注冊(cè)的Contentprovider
public ProviderInfo[] providers;
}
PackageInfo的子類ApplicationInfo中封裝了:
程序名稱
程序圖標(biāo)等信息
如何獲取這些信息的呢?
查看ApplicationInfo源碼
//ApplicationInfo類的繼承關(guān)系,進(jìn)行了序列化,可在進(jìn)程間傳遞
public class ApplicationInfo extends PackageItemInfo implements Parcelable {
//ApplicationInfo類中的屬性
public int flags = 0;
//判斷是否是系統(tǒng)程序用到的常量,這里為什么用<<(邏輯左移)沒搞明白,計(jì)算后的值十進(jìn)制還是1
public static final int FLAG_SYSTEM = 1<<0;
/**判斷是否是系統(tǒng)程序計(jì)算方法,
(flags & ApplicationInfo.FLAG_SYSTEM) != 0表示是系統(tǒng)程序*/
}
ApplicationInfo繼承PackageItemInfo類。
查看PackageItemInfo源碼
//具體實(shí)現(xiàn)方法封裝在父類PackageItemInfo類中
public class PackageItemInfo {
//獲取程序名稱
public CharSequence loadLabel(PackageManager pm);
//獲取程序圖標(biāo)
public Drawable loadIcon(PackageManager pm);
}
知道了程序信息封裝在PackageInfo類中。如何獲取PackageInfo對(duì)象?
SDK提供了包管理類PackageManager,負(fù)責(zé)獲取PackageInfo對(duì)象的。
查看PackageManager源碼
public abstract class PackageManager {//是一個(gè)抽象類
/**以下都是抽象方法*/
//第一個(gè)參數(shù):包名 ;第二個(gè)參數(shù):為附加條件選項(xiàng)(如:GET_CONFIGURATIONS獲取配置)
PackageInfo getPackageInfo(String packageName, int flags);
//獲取已安裝程序信息對(duì)象的列表
List<PackageInfo> getInstalledPackages(int flags);
//根據(jù)程序申請(qǐng)的權(quán)限過濾,申請(qǐng)某些特定權(quán)限的程序
List<PackageInfo> getPackagesHoldingPermissions(String[] permissions,
int flags);
List<PackageInfo> getPreferredPackages(int flags);
//獲取程序大小,遺憾是@hide方法,只能通過反射機(jī)制調(diào)用
void getPackageSizeInfo(String packageName, IPackageStatsObserver observer);
}
獲取程序大小請(qǐng)移步到另一篇文章,詳細(xì)講解獲取程序大小
具體實(shí)現(xiàn),這篇文章不去詳細(xì)講解。
我們需要追蹤到哪個(gè)類中可獲取該對(duì)象實(shí)例即可,查看源碼,
ContextWrapper類中提供獲取PackageManager對(duì)象的函數(shù)
//ContextWrapper類中g(shù)etPackageManager函數(shù)可獲取到PackageManager對(duì)象
public class ContextWrapper extends Context {
public PackageManager getPackageManager() {
return mBase.getPackageManager();
}
}
ContextWrapper類的子類
//從以下繼承關(guān)系可以知道這些對(duì)象都可直接調(diào)用getPackageManager方法得到PackageManager對(duì)象
class Application extends ContextWrapper;
class ContextThemeWrapper extends ContextWrapper;
class Activity extends ContextThemeWrapper;
//Service為抽象類,需要實(shí)現(xiàn)Service調(diào)用getPackageManager方法獲取PackageManager對(duì)象
public abstract class Service extends ContextWrapper;
開發(fā)中常遇到以下兩種情形:
- 1知道包名,獲取該程序的信息
- 2獲取已安裝的程序信息
獲取包管理類PackageManager
// Application Activity Service中都可直接調(diào)用getPackageManager()方法獲取PackageManager
PackageManager pm ;
pm= Application.getPackageManager();
pm = Activity.getPackageManager();
pm = Service.getPackageManager();
包管理對(duì)象獲取程序信息
// 知道包名,獲取該程序信息
PackageInfo pi = pm.getPackageInfo(packageName,PackageManager.GET_CONFIGURATIONS);
//獲取設(shè)備上安裝的程序信息
//PackageManager.GET_UNINSTALLED_PACKAGES常量代表已經(jīng)卸載的也會(huì)收集到
List<PackageInfo> apps;
apps = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
獲取到PackageInfo對(duì)象,任務(wù)完成,獲取你想要的數(shù)據(jù)吧。