PackageManager:管理应用程序包
功能:
- 安装,卸载应用
- 查询permission相关信息
- 查询Application相关信息(application,activity,receiver,service,provider及相应属性等)
- 查询已安装应用
- 增加,删除permission
- 清除用户数据、缓存,代码段等
使用方法:
在Android中,为应用包的安装,删除各种操作服务的,是PackageManagerSerivce,简称PMS.
如果想要调用PMS的服务,则可以通过Context去调用getPackageManager方法。
/** Return PackageManager instance to find global package information. */
public abstract PackageManager getPackageManager();
这个定义于Context.java中:
查询Application相关信息
应用组件集合查询API
一、根据包名获取应用信息
ApplicationInfo getApplicationInfo (String packageName,int flags)
参数:flags
- GET_SHARED_LIBRARY_FILES:获取so库的安装路径,然后可以通过ApplicationInfo的sharedLibraryFiles属性来读取相关信息。
- MATCH_SYSTEM_ONLY:只包括带有系统属性的
- MATCH_UNINSTALLED_PACKAGES:即使是应用被uninstall了,但只要保留了数据,也可以被搜出来。
二、获取当前系统上安装的所有的应用程序
List<ApplicationInfo> getInstalledApplications (int flags);
参数:flags
- GET_META_DATA:
- GET_SHARED_LIBRARY_FILES:获取so库的安装路径,然后可以通过ApplicationInfo的sharedLibraryFiles属性来读取相关信息。
- MATCH_SYSTEM_ONLY:只包括带有系统属性的
- MATCH_UNINSTALLED_PACKAGES:即使是应用被uninstall了,但只要保留了数据,也可以被搜出来。
三、获取当前系统中安装的所有包
List<PackageInfo> getInstalledPackages (int flags)
参数:flags
* PackageManager.GET_ACTIVITIES
* PackageManager.GET_CONFIGURATIONS
* PackageManager.GET_GIDS
* PackageManager.GET_INSTRUMENTATION
* PackageManager.GET_INTENT_FILTERS
* PackageManager.GET_META_DATA
* PackageManager.GET_PERMISSIONS
* PackageManager.GET_PROVIDERS
* PackageManager.GET_RECEIVERS
* PackageManager.GET_SERVICES
* PackageManager.GET_SHARED_LIBRARY_FILES
* PackageManager.GET_SIGNATURES
* PackageManager.GET_URI_PERMISSION_PATTERN
四、根据包名获取一个包的信息
PackageInfo getPackageInfo (String packageName, int flags);
参数:flags
* PackageManager.GET_ACTIVITIES
* PackageManager.GET_CONFIGURATIONS
* PackageManager.GET_GIDS
* PackageManager.GET_INSTRUMENTATION
* PackageManager.GET_INTENT_FILTERS
* PackageManager.GET_META_DATA
* PackageManager.GET_PERMISSIONS
* PackageManager.GET_PROVIDERS
* PackageManager.GET_RECEIVERS
* PackageManager.GET_SERVICES
* PackageManager.GET_SHARED_LIBRARY_FILES
* PackageManager.GET_SIGNATURES
* PackageManager.GET_URI_PERMISSION_PATTERN
五、从包文件中读取getPackageArchiveInfo
public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags)
参数:flags
* PackageManager.GET_ACTIVITIES
* PackageManager.GET_CONFIGURATIONS
* PackageManager.GET_GIDS
* PackageManager.GET_INSTRUMENTATION
* PackageManager.GET_INTENT_FILTERS
* PackageManager.GET_META_DATA
* PackageManager.GET_PERMISSIONS
* PackageManager.GET_PROVIDERS
* PackageManager.GET_RECEIVERS
* PackageManager.GET_SERVICES
* PackageManager.GET_SHARED_LIBRARY_FILES
* PackageManager.GET_SIGNATURES
* PackageManager.GET_URI_PERMISSION_PATTERN
六、根据Activity的名称来获取ActivityInfo
ActivityInfo getActivityInfo (ComponentName component, int flags)
ComponentName是个什么类呢?其实就是包名和类名的组合:
//Create a new component identifier.
ComponentName(String pkg, String cls);
特别要注意,类名是要全路径名,不然会找不到的!
try {
final ActivityInfo ai = mPm.getActivityInfo(new ComponentName("com.android.htmlviewer","com.android.htmlviewer.HTMLViewerActivity"),
PackageManager.GET_META_DATA | PackageManager.MATCH_ALL);
Log.d(TAG,"ActivityInfo:"+ai.toString());
Log.d(TAG,"ActivityInfo,parentActivityName is:"+ai.parentActivityName);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG,"testGetActivityInfo error",e);
}
参数:
flags
七、根据名字获取Instrumentation信息,这个信息在AndroidManifest.xml中的中定义
InstrumentationInfo getInstrumentationInfo (ComponentName className, int flags);
八、通过ComponentName获取ServiceInfo
ServiceInfo getServiceInfo (ComponentName component, int flags);
九、根据ComponentName获取ReceiverInfo
有同学问了,既然可以查询ActivityInfo,ServiceInfo,ReceiverInfo,四大组件中都有三个了,那么为什么没有查询ProviderInfo的呢?
getProviderInfo这个API直到Android 2.3时才有
ActivityInfo getReceiverInfo (ComponentName component, int flags);
十、Android 2.3新增API - getProviderInfo
ProviderInfo getProviderInfo (ComponentName component, int flags);
Uid/Gid相关查询API
一、读取和包名相关的Group id
ProviderInfo getProviderInfo (ComponentName component, int flags);
public void testGetPackageGids(){
try {
int[] gids = mPm.getPackageGids("com.android.externalstorage");
if(gids!=null){
for(int gid:gids){
Log.d(TAG,"gid:"+gid);
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG,"testGetPackageGids error",e);
}
}
输出
08-12 15:30:36.783 2329-2329/? D/TestPackageManager: gid:1023
08-12 15:30:36.783 2329-2329/? D/TestPackageManager: gid:10
二、getPackagesForUid
ProviderInfo getProviderInfo (ComponentName component, int flags);
public void testGetPackagesForUid(){
String[] packagesForUid = mPm.getPackagesForUid(1000);
if(packagesForUid!=null){
for(String package1 : packagesForUid){
Log.d(TAG, "Package name in 1000:"+package1);
}
}
}
输出
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.thermalmanager
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.batterywarning
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.connectivity
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.server.telecom
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.inputdevices
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.settings
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:android
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.atci.service
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.providers.settings
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.vpndialogs
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.ppl
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.location.fused
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.nlpservice
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.mediatek.schpwronoff
08-12 16:42:38.730 4736-4736/? D/TestPackageManager: Package name in 1000:com.android.keychain
三、查询一个uid对应的名字
String getNameForUid (int uid);
public void testGetNameForUid(){
String name = mPm.getNameForUid(1000);
Log.d(TAG,"Name for uid 1000 is:"+name);
}
输出
08-13 16:55:05.207 8899-8899/? D/TestPackageManager: Name for uid 1000 is:android.uid.system:1000
Uid/Gid相关查询API
一、查询系统中运行的ContentProvider
List<ProviderInfo> queryContentProviders (String processName,int uid,int flags)
参数:
进程名:如果希望列出所有的,就为空
uid:如果进程名不为空,需要指定uid
标志位:match的属性
public void testQueryContentProviders() {
List<ProviderInfo> pis = mPm.queryContentProviders(null, 0, PackageManager.MATCH_ALL);
if (pis != null) {
for (ProviderInfo pri : pis) {
Log.d(TAG, "Provider info:" + pri);
}
}
}
输出
08-15 11:41:39.758 18259-18259/? D/TestPackageManager: Provider info:ContentProviderInfo{name=settings className=com.android.providers.settings.SettingsProvider}
08-15 11:41:39.758 18259-18259/? D/TestPackageManager: Provider info:ContentProviderInfo{name=com.tencent.mm.plugin.ext.NearBy className=com.tencent.mm.plugin.ext.provider.ExtControlProviderNearBy}
08-15 11:41:39.758 18259-18259/? D/TestPackageManager: Provider info:ContentProviderInfo{name=mwimsg className=com.android.providers.telephony.MwiProvider}
二、根据包名查询Instrumentation
List<InstrumentationInfo> queryInstrumentation (String targetPackage,int flags);
参数:
包名:如果是所有的包,则给null
标志:只支持GET_META_DATA这一个。
public void testQueryInstrumentation(){
List<InstrumentationInfo> list = mPm.queryInstrumentation(null,PackageManager.GET_META_DATA);
if(list!=null){
for(InstrumentationInfo ii : list){
Log.d(TAG,"Instrumentation info:"+ii.toString());
}
}
}
根据Intent查询相关组件的API
一、根据Intent查询可以处理这个Intent的所有BroadcastReceivers
List<ResolveInfo> queryBroadcastReceivers (Intent intent,int flags);
二、查询可以处理这个Intent的所有Activity
List<ResolveInfo> queryIntentActivities (Intent intent,int flags);
参数:
Intent
参数:MATCH_ALL等
三、queryIntentActivityOptions跟queryIntentActivities基本一样,支持更多的查询条件
List<ResolveInfo> queryIntentActivityOptions (ComponentName caller, Intent[] specifics, Intent intent,int flags);
四、查询可以处理这个Intent的所有Service
List<ResolveInfo> queryIntentServices (Intent intent,int flags);
大家都知道,Android有四大组件:Activity, Service, BroadcastReceiver和ContentProvider。前面三个组件都可以通过Intent查询了,为什么没有queryIntentContentProviders呢?
queryIntentContentProviders直到Android 4.4才增加进来。
五、Android 4.4新增API: queryIntentContentProviders,查询可以处理这个Intent的所有ContentProvider们
List<ResolveInfo> queryIntentContentProviders (Intent intent, int flags);
根据Intent查询最佳应用组件API
一、resolveActivity:查找最适合些Intent的Activity
ResolveInfo resolveActivity (Intent intent, int flags);
二、resolveContentProvider:查找最适合些Intent的ContentProvider
ResolveInfo resolveContentProvider (Intent intent, int flags);
三、resolveService:查找最适合些Intent的服务
ResolveInfo resolveService (Intent intent, int flags);
上面3个API都是拿到了Intent再去判断它最适合的应用组件。那么,我们想要做逆运算,知道一个包了,如何去得到启动它的Intent呢?
这个API直到Android 1.5(API 3)时才加入系统中:getLaunchIntentForPackage
事、resolveService:查找最适合些Intent的服务
Intent getLaunchIntentForPackage (String packageName);
例程:我们想获取微信的启动Intent:
public void testGetLaunchIntentForPackage() {
Intent intent = mPm.getLaunchIntentForPackage("com.tencent.mm");
if (intent != null) {
Log.d(TAG, "Intent for Launch this is:" + intent.toString());
}
}
运行结果如下,原来启动微信的界面是com.tencent.mm.ui.LauncherUI。
08-15 14:23:59.909 18954-18954/? D/TestPackageManager: Intent for Launch this is:Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=x10000000 pkg=com.tencent.mm cmp=com.tencent.mm/.ui.LauncherUI }
一个查询应用信息的例子
package com.bourne.android_common.PackageManagerDemo;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.bourne.android_common.R;
import com.bourne.common_library.utils.Logout;
import java.util.Collections;
import java.util.List;
public class PackagerManagerActivity extends AppCompatActivity {
// 所有应用程序
public static final int FILTER_ALL_APP = 0;
// 系统程序
public static final int FILTER_SYSTEM_APP = 1;
// 第三方应用程序
public static final int FILTER_THIRD_APP = 2;
// 安装在SDCard的应用程序
public static final int FILTER_SDCARD_APP = 3;
private PackageManager pm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_packager_manager);
// Logout.e("获取所有程序信息");
// getPackageInfo();
// Logout.e("根据包名获取应用信息");
// getAppInfoByPackageName("com.bourne.android_common");
// Logout.e("获取所有程序的Activity");
// getInstalledPackages();
Logout.e("系统程序");
filterApp(FILTER_SYSTEM_APP);
Logout.e("第三方应用程序");
filterApp(FILTER_THIRD_APP);
Logout.e("安装在SDCard的应用程序");
filterApp(FILTER_SDCARD_APP);
}
/**
* 获取所有程序信息
* 通过PackageManager的queryIntentActivities方法,
* 查询系统中所有满足ACTION_MAIN和CATEGORY_LAUNCHER的应用程序,
* 获取他们的程序名、包名、入口类名。
*/
private void getPackageInfo() {
pm = this.getPackageManager();
//action为ACTION_MAIN的
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_DEFAULT);
List<ResolveInfo> list = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
//根据显示名称排序
Collections.sort(list, new ResolveInfo.DisplayNameComparator(pm));
for (ResolveInfo info : list) {
//应用名
String appName = info.loadLabel(pm).toString();
//包名
String packageName = info.activityInfo.packageName;
//入口类名
String launchClassName = info.activityInfo.name;
Logout.i("应用名:" + appName + "\n包名:" + packageName + "\n入口类名:" + launchClassName);
}
}
/**
* 筛选
*
* @param type
*/
private void filterApp(int type) {
pm = this.getPackageManager();
//getInstalledApplications:获取当前系统上安装的所有的应用程序
List<ApplicationInfo> list = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
Collections.sort(list, new ApplicationInfo.DisplayNameComparator(pm));
switch (type) {
case FILTER_ALL_APP:
for (ApplicationInfo info : list) {
getAppInfo(info);
}
break;
case FILTER_SYSTEM_APP:
for (ApplicationInfo info : list) {
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
getAppInfo(info);
}
}
break;
case FILTER_THIRD_APP:
for (ApplicationInfo info : list) {
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
getAppInfo(info);
}
}
break;
case FILTER_SDCARD_APP:
for (ApplicationInfo info : list) {
if (info.flags == ApplicationInfo.FLAG_SYSTEM) {
getAppInfo(info);
}
}
break;
}
}
/**
* 获取应用信息
*/
private void getAppInfo(ApplicationInfo applicationInfo) {
// 应用名
String appName = applicationInfo.loadLabel(pm).toString();
// 包名
String packageName = applicationInfo.packageName;
//入口类名
String launchClassName = applicationInfo.name;
//进程名
String processName = applicationInfo.processName;
Logout.i("应用名:" + appName + "\n包名:" + packageName + "\n入口类名:" + launchClassName + "\n进程名:" + processName);
}
/**
* 根据包名获取应用信息
*/
private void getAppInfoByPackageName(String packageName) {
pm = this.getPackageManager();
ApplicationInfo ai = null;
try {
ai = pm.getApplicationInfo(packageName,
PackageManager.GET_META_DATA | PackageManager.GET_SHARED_LIBRARY_FILES);
// 应用名
String appName = ai.loadLabel(pm).toString();
//入口类名
String launchClassName = ai.name;
//进程名
String processName = ai.processName;
//描述
String loadDescription = "" + ai.loadDescription(pm);
//共享库
String nativeLibraryDir = ai.nativeLibraryDir;
Logout.i("应用名:" + appName + "\n入口类名:" + launchClassName + "\n进程名:" + processName + "\n描述:" + loadDescription + "\n共享库:" + nativeLibraryDir);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取当前系统中安装的所有包
*/
public void getInstalledPackages() {
pm = this.getPackageManager();
List<PackageInfo> piList = pm.getInstalledPackages(PackageManager.GET_ACTIVITIES |
PackageManager.GET_CONFIGURATIONS |
PackageManager.GET_GIDS |
PackageManager.GET_INSTRUMENTATION |
PackageManager.GET_INTENT_FILTERS |
PackageManager.GET_META_DATA |
PackageManager.GET_PERMISSIONS |
PackageManager.GET_PROVIDERS |
PackageManager.GET_RECEIVERS |
PackageManager.GET_SERVICES |
PackageManager.GET_SHARED_LIBRARY_FILES |
PackageManager.GET_SIGNATURES |
PackageManager.GET_URI_PERMISSION_PATTERNS);
if (piList != null) {
for (PackageInfo pi : piList) {
Logout.i("包信息:" + pi.toString());
Logout.i("包名:" + pi.packageName);
Logout.i("包共享user id" + pi.sharedUserId);
final ActivityInfo[] ais = pi.activities;
if (ais != null) {
for (ActivityInfo ai : ais) {
Logout.i("Activity:{" + pi.packageName + "}:" + ai.name);
}
}
final InstrumentationInfo[] iis = pi.instrumentation;
if (iis != null) {
for (InstrumentationInfo is : iis) {
Logout.i("Instrumentation信息" + is.toString());
}
}
final ProviderInfo[] pis = pi.providers;
if (pis != null) {
for (ProviderInfo pri : pis) {
Logout.i("Provider信息:" + pri);
}
}
}
}
}
}
系统应用信息:
第三方应用信息
获取所有的activity
参考文章
- Android应用生死轮回的那些事儿(4) - 武器库(2)-应用组件查询相关
- Android应用生死轮回的那些事儿(2) - PackageManager
- 几个Info系列的种的总结
- Android随笔之——PackageManager详解
- Android中获取应用程序(包)的信息—–PackageManager的使用(一)
- Android获取应用程序信息——PackageManager的基本使用