一、PackageManager的功能:
1、安裝,卸載應用
2、查詢permission相關信息
3、查詢Application相關信息(application,activity,receiver,service,provider及相應屬性等)
4、查詢已安裝應用
5、增加,刪除permission
6、清除用戶數據、緩存,代碼段等
二、PackageManager相關類和方法介紹:
1、PackageManager類
復制代碼
說明: 獲得已安裝的應用程序信息 。可以通過getPackageManager()方法獲得。
常用方法:
public abstract PackageManager getPackageManager()
功能:獲得一個PackageManger對象
public abstract Drawable getApplicationIcon(String packageName)
參數: packageName 包名
功能:返回給定包名的圖標,否則返回null
public abstract ApplicationInfo getApplicationInfo(String packageName, int flags)
參數:
packagename 包名
flags 該ApplicationInfo是此flags標記,通常可以直接賦予常數0即可
功能:返回該ApplicationInfo對象
public abstract List<ApplicationInfo> getInstalledApplications(int flags)
參數:
flag為一般為GET_UNINSTALLED_PACKAGES,那麼此時會返回所有ApplicationInfo。我們可以對ApplicationInfo
的flags過濾,得到我們需要的。
功能:返回給定條件的所有PackageInfo
public abstract List<PackageInfo> getInstalledPackages(int flags)
參數如上
功能:返回給定條件的所有PackageInfo
public abstract ResolveInfo resolveActivity(Intent intent, int flags)
參數:
intent 查尋條件,Activity所配置的action和category
flags: MATCH_DEFAULT_ONLY :Category必須帶有CATEGORY_DEFAULT的Activity,才匹配
GET_INTENT_FILTERS :匹配Intent條件即可
GET_RESOLVED_FILTER :匹配Intent條件即可
功能 :返回給定條件的ResolveInfo對象(本質上是Activity)
public abstract List<ResolveInfo> queryIntentActivities(Intent intent, int flags)
參數同上
功能 :返回給定條件的所有ResolveInfo對象(本質上是Activity),集合對象
public abstract ResolveInfo resolveService(Intent intent, int flags)
參數同上
功能 :返回給定條件的ResolveInfo對象(本質上是Service)
public abstract List<ResolveInfo> queryIntentServices(Intent intent, int flags)
參數同上
功能 :返回給定條件的所有ResolveInfo對象(本質上是Service),集合對象
復制代碼
2、PackageItemInfo類
說明: AndroidManifest.xml文件中所有節點的基類,提供了這些節點的基本信息:label、icon、 meta-data。它並不直接使用,而是由子類繼承然後調用相應方法。
3、ApplicationInfo類 繼承自 PackageItemInfo類
復制代碼
說明:獲取一個特定引用程序中<application>節點的信息。
字段說明:
flags字段: FLAG_SYSTEM 系統應用程序
FLAG_EXTERNAL_STORAGE 表示該應用安裝在sdcard中
常用方法繼承至PackageItemInfo類中的loadIcon()和loadLabel()
復制代碼
4、ActivityInfo類 繼承自 PackageItemInfo類
說明: 獲得應用程序中<activity/>或者 <receiver/>節點的信息 。我們可以通過它來獲取我們設置的任何屬性,包括theme 、launchMode、launchmode等
常用方法繼承至PackageItemInfo類中的loadIcon()和loadLabel()
5、ServiceInfo類 繼承自 PackageItemInfo類
說明:與ActivityInfo類似,代表<service>節點信息
6、ResolveInfo類
說明:根據<intent>節點來獲取其上一層目錄的信息,通常是<activity>、<receiver>、<service>節點信息。
常用方法有loadIcon(PackageManager pm)和loadLabel(PackageManager pm)
三、實例講解:
1、通過PackageManager的queryIntentActivities方法,查詢系統中所有滿足ACTION_MAIN和CATEGORY_LAUNCHER的應用程序,獲取他們的程序名、包名、入口類名。(水平有限,ListView沒學好,不能做一個簡易啟動器,不過啟動應用的原理在之前的文章中有提到,有興趣的可以去看看:Android隨筆之——Activity中啟動另一應用)
MainActivity.java
復制代碼
1 package com.example.packagemanager;
2
3 import java.util.Collections;
4 import java.util.List;
5
6 import android.app.Activity;
7 import android.content.Intent;
8 import android.content.pm.PackageManager;
9 import android.content.pm.ResolveInfo;
10 import android.os.Bundle;
11
12 public class MainActivity extends Activity {
13
14 @Override
15 protected void onCreate(Bundle savedInstanceState) {
16 super.onCreate(savedInstanceState);
17 setContentView(R.layout.activity_main);
18 getAppInfo();
19 }
20
21 private void getAppInfo() {
22 // 獲取PackageManager對象
23 PackageManager pm = this.getPackageManager();
24 // 設置<intent-filter>標簽內需要滿足的條件
25 Intent intent = new Intent(Intent.ACTION_MAIN, null);
26 intent.addCategory(Intent.CATEGORY_DEFAULT);
27
28 // 通過queryIntentActivities獲取ResolveInfo對象
29 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent,
30 PackageManager.MATCH_DEFAULT_ONLY);
31
32 // 調用系統排序,根據name排序
33 // 該排序很重要,否則只能顯示系統應用,不能顯示第三方應用
34 // 其實我測試發現有沒有其實是一樣的,就是輸出的順序是亂的
35 Collections.sort(resolveInfos,
36 new ResolveInfo.DisplayNameComparator(pm));
37
38 for (ResolveInfo resolveInfo : resolveInfos) {
39 String appName = resolveInfo.loadLabel(pm).toString();// 獲取應用名稱
40 String packageName = resolveInfo.activityInfo.packageName;// 包名
41 String className = resolveInfo.activityInfo.name;// 入口類名
42 System.out.println("程序名:" + appName + " 包名:" + packageName
43 + " 入口類名:" + className);
44 }
45 }
46
47 }
復制代碼
輸出結果:
2、通過PackageManager的queryInstalledApplications方法,過濾掉出系統應用、第三方應用、安裝在SDCard上的應用。
MainActivity.java
復制代碼
1 package com.example.packagemanager;
2
3 import java.util.Collections;
4 import java.util.List;
5
6 import android.app.Activity;
7 import android.content.pm.ApplicationInfo;
8 import android.content.pm.PackageManager;
9 import android.os.Bundle;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12
13 public class MainActivity extends Activity implements OnClickListener {
14
15 public static final int FILTER_ALL_APP = 0; // 所有應用程序
16 public static final int FILTER_SYSTEM_APP = 1; // 系統程序
17 public static final int FILTER_THIRD_APP = 2; // 第三方應用程序
18 public static final int FILTER_SDCARD_APP = 3; // 安裝在SDCard的應用程序
19 private PackageManager pm;
20
21 @Override
22 protected void onCreate(Bundle savedInstanceState) {
23 super.onCreate(savedInstanceState);
24 setContentView(R.layout.activity_main);
25
26 findViewById(R.id.btn_all).setOnClickListener(this);
27 findViewById(R.id.btn_system).setOnClickListener(this);
28 findViewById(R.id.btn_third).setOnClickListener(this);
29 findViewById(R.id.btn_sdcard).setOnClickListener(this);
30 }
31
32 /**
33 * 過濾,選擇是系統應用、第三方應用或者SDCard應用
34 */
35 private void filterApp(int type) {
36 // 獲取PackageManager對象
37 pm = getPackageManager();
38 // 查詢已經安裝的應用程序
39 List<ApplicationInfo> applicationInfos = pm
40 .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
41 // 排序
42 Collections.sort(applicationInfos,
43 new ApplicationInfo.DisplayNameComparator(pm));
44
45 switch (type) {
46 case FILTER_ALL_APP:// 所有應用
47 for (ApplicationInfo applicationInfo : applicationInfos) {
48 getAppInfo(applicationInfo);
49 }
50 break;
51 case FILTER_SYSTEM_APP:// 系統應用
52 for (ApplicationInfo applicationInfo : applicationInfos) {
53 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
54 getAppInfo(applicationInfo);
55 }
56 }
57 case FILTER_THIRD_APP:// 第三方應用
58
59 for (ApplicationInfo applicationInfo : applicationInfos) {
60 // 非系統應用
61 if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
62 getAppInfo(applicationInfo);
63 }
64 // 系統應用,但更新後變成不是系統應用了
65 else if ((applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
66 getAppInfo(applicationInfo);
67 }
68 }
69 case FILTER_SDCARD_APP:// SDCard應用
70 for (ApplicationInfo applicationInfo : applicationInfos) {
71 if (applicationInfo.flags == ApplicationInfo.FLAG_SYSTEM) {
72 getAppInfo(applicationInfo);
73 }
74 }
75 default:
76 break;
77 }
78 }
79
80 /**
81 * 獲取應用信息
82 */
83 private void getAppInfo(ApplicationInfo applicationInfo) {
84 String appName = applicationInfo.loadLabel(pm).toString();// 應用名
85 String packageName = applicationInfo.packageName;// 包名
86 System.out.println("應用名:" + appName + " 包名:" + packageName);
87 }
88
89 @Override
90 public void onClick(View arg0) {
91 switch (arg0.getId()) {
92 case R.id.btn_all:
93 System.out.println("輸出所有應用信息:\n");
94 filterApp(FILTER_ALL_APP);
95 break;
96 case R.id.btn_system:
97 System.out.println("輸出系統應用信息:\n");
98 filterApp(FILTER_SYSTEM_APP);
99 break;
100 case R.id.btn_third:
101 System.out.println("輸出第三方應用信息:\n");
102 filterApp(FILTER_THIRD_APP);
103 break;
104 case R.id.btn_sdcard:
105 System.out.println("輸出SDCard應用信息:\n");
106 filterApp(FILTER_SDCARD_APP);
107 break;
108
109 default:
110 break;
111 }
112 }
113
114 }
復制代碼
activity_main.xml
復制代碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="所有應用" />
<Button
android:id="@+id/btn_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="系統應用" />
<Button
android:id="@+id/btn_third"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第三方應用" />
<Button
android:id="@+id/btn_sdcard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SDCard應用" />
</LinearLayout>