案例:PackageManager
阅读原文时间:2021年04月20日阅读:1

2019独角兽企业重金招聘Python工程师标准>>>

1。http://blog.csdn.net/qinjuning/article/details/6867806    此人博客写的不错,有待研究啊

2。http://blog.csdn.net/liranke/article/details/17717571 简直就是超级大神!

3。下面来看咱们的案例

PackageManager pm = getPackageManager();

下面是获取当前应用的基本信息:

//图标

 Drawable app_icon =pm.getApplicationIcon(getApplicationInfo());

// 获取名称
  String app_name = (String) pm.getApplicationLabel(getApplicationInfo());

PackageInfopackageInfo = pm.getPackageInfo(getPackageName(), PackageManager.GET_UNINSTALLED_PACKAGES);

mAppInfo.setAppLabel((String) packageInfo.applicationInfo.loadLabel(pm));
   //mAppInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(pm));
   mAppInfo.setVersionName(packageInfo.versionName);
   mAppInfo.setVersionCode(packageInfo.versionCode);
   mAppInfo.setPackageName(packageInfo.packageName);
   mAppInfo.setFirstInstallTime(packageInfo.firstInstallTime);
   mAppInfo.setLastUpdateTime(packageInfo.lastUpdateTime);

下面是获取手机中应用的基本信息:

List installedPackages = pm.getInstalledPackages(0);
  for (PackageInfo packageInfo : installedPackages) {
   AppInfo mAppInfo = new AppInfo();
   mAppInfo.setAppLabel((String) packageInfo.applicationInfo.loadLabel(pm));
   //mAppInfo.setAppIcon(packageInfo.applicationInfo.loadIcon(pm));
   mAppInfo.setVersionName(packageInfo.versionName);
   mAppInfo.setVersionCode(packageInfo.versionCode);
   mAppInfo.setPackageName(packageInfo.packageName);
   mAppInfo.setFirstInstallTime(packageInfo.firstInstallTime);
   mAppInfo.setLastUpdateTime(packageInfo.lastUpdateTime);
   
   // Only display the non-system app info
   if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    // 如果非系统应用,则添加至appList
    mAppInfos.add(mAppInfo);
   }
  }

下面是获取手机桌面上应用的基本信息:

Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.addCategory(Intent.CATEGORY_LAUNCHER);
        List queryIntentActivities = pm.queryIntentActivities(intent, 0);         for (ResolveInfo resolveInfo : queryIntentActivities) {
         AppInfo mAppInfo = new AppInfo();
   mAppInfo.setAppIcon(resolveInfo.loadIcon(pm));
   mAppInfo.setAppLabel((String)resolveInfo.loadLabel(pm));
   mAppInfo.setPackageName(resolveInfo.activityInfo.packageName);
   mAppInfos.add(mAppInfo);
  }

效果如图:

关于apk的安装路径和大小:

豌豆荚
10-04 03:38:02.178: I/System.out(2458): sourceDir:/data/app/com.wandoujia.phoenix2-1.apk
10-04 03:38:02.178: I/System.out(2458): dataDir:/data/data/com.wandoujia.phoenix2
10-04 03:38:02.178: I/System.out(2458): publicSourceDir:/data/app/com.wandoujia.phoenix2-1.apk
10-04 03:38:02.178: I/System.out(2458): 豌豆荚的apk大小:5.13MB

API Demos
10-04 03:38:02.002: I/System.out(2458): sourceDir:/data/app/com.example.android.apis-1.apk
10-04 03:38:02.006: I/System.out(2458): dataDir:/data/data/com.example.android.apis
10-04 03:38:02.006: I/System.out(2458): publicSourceDir:/data/app/com.example.android.apis-1.apk
10-04 03:38:02.026: I/System.out(2458): API Demos的apk大小:4.58MB

电话
10-04 03:38:01.802: I/System.out(2458): sourceDir:/system/app/VoiceDialer.apk
10-04 03:38:01.802: I/System.out(2458): dataDir:/data/data/com.android.voicedialer
10-04 03:38:01.802: I/System.out(2458): publicSourceDir:/system/app/VoiceDialer.apk
10-04 03:38:01.810: I/System.out(2458): Voice Dialerapk的大小:124KB

闹钟
10-04 03:38:02.202: I/System.out(2458): sourceDir:/system/app/DeskClock.apk
10-04 03:38:02.202: I/System.out(2458): dataDir:/data/data/com.android.deskclock
10-04 03:38:02.202: I/System.out(2458): publicSourceDir:/system/app/DeskClock.apk
10-04 03:38:02.202: I/System.out(2458): Clockapk大小:2.14MB

代码实现:
List installedApplications = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
  for (ApplicationInfo applicationInfo : installedApplications) {
   String sourceDir=applicationInfo.sourceDir;//安装路径
   String dataDir=applicationInfo.dataDir;
   String publicSourceDir=applicationInfo.publicSourceDir;
   System.out.println("sourceDir:"+sourceDir);
   System.out.println("dataDir:"+dataDir);
   System.out.println("publicSourceDir:"+publicSourceDir);
   int size = Integer.valueOf((int) new File(publicSourceDir).length());
   System.out.println(applicationInfo.loadLabel(pm)+"的apk大小:"+Formatter.formatFileSize(this, size));
  }

这个大小和茄子快传,快牙,闪传,豌豆荚上的软件管理中显示的是一致的

应用程序的大小:

豌豆荚
10-04 03:58:18.234: I/System.out(2538): cacheSize:28.00KB,codeSize:11.11MB,dataSize:8.96MB
10-04 03:58:18.238: I/System.out(2538): externalCacheSize:0.00B,externalCodeSize:0.00B,externalDataSize:0.00BexternalMediaSize:0.00B,externalObbSize:0.00B
10-04 03:58:18.238: I/System.out(2538): 豌豆荚的总大小:20.10MB

API Demos
10-04 03:58:18.122: I/System.out(2538): cacheSize:12.00KB,codeSize:6.43MB,dataSize:0.00B
10-04 03:58:18.122: I/System.out(2538): externalCacheSize:0.00B,externalCodeSize:0.00B,externalDataSize:0.00BexternalMediaSize:0.00B,externalObbSize:0.00B
10-04 03:58:18.122: I/System.out(2538): API Demos的总大小:6.44MB

电话
10-04 03:58:18.310: I/System.out(2538): cacheSize:12.00KB,codeSize:60.00KB,dataSize:12.00KB
10-04 03:58:18.310: I/System.out(2538): externalCacheSize:0.00B,externalCodeSize:0.00B,externalDataSize:0.00BexternalMediaSize:0.00B,externalObbSize:0.00B
10-04 03:58:18.310: I/System.out(2538): Voice Dialer的总大小:84.00KB

闹钟
10-04 03:58:17.818: I/System.out(2538): cacheSize:12.00KB,codeSize:392KB,dataSize:60.00KB
10-04 03:58:17.862: I/System.out(2538): externalCacheSize:0.00B,externalCodeSize:0.00B,externalDataSize:0.00BexternalMediaSize:0.00B,externalObbSize:0.00B
10-04 03:58:17.866: I/System.out(2538): Clock的总大小:464KB

目录结构如下:

介绍一篇aidl的文章:http://www.cnblogs.com/rookietong/archive/2013/03/16/2962623.html

android.content.pm,这个包及包下的所有东西都是死的,是系统的aidl文件,这些文件可以在github上下载。

IPackageDataObserver.aidl:

package android.content.pm;

/**
 * API for package data change related callbacks from the Package Manager.
 * Some usage scenarios include deletion of cache directory, generate
 * statistics related to code, data, cache usage(TODO)
 * {@hide}
 */
oneway interface IPackageDataObserver {
    void onRemoveCompleted(in String packageName, boolean succeeded);
}

IPackageStatsObserver.aidl:

package android.content.pm;

import android.content.pm.PackageStats;
/**
 * API for package data change related callbacks from the Package Manager.
 * Some usage scenarios include deletion of cache directory, generate
 * statistics related to code, data, cache usage(TODO)
 * {@hide}
 */
oneway interface IPackageStatsObserver {
   
    void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
}

PackageStats.aidl:
package android.content.pm;

parcelable  PackageStats;

软件包的大小封装在PackageStats这个类中,要获取这个类不能用构造方法获取,这一点也不知道为什么。他是通过PackageManager的hide方法getPackageSizeInfo()来得到,但是要调用这个hide方法就要用java的反射机制,不然pm.不出来。应用aidl的代码如下:

List queryIntentActivities = pm.queryIntentActivities(intent, 0);

for (final ResolveInfo resolveInfo : queryIntentActivities) {
   try {
    Method getPackageSizeInfo = pm.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
    getPackageSizeInfo.invoke(pm, resolveInfo.activityInfo.packageName, new IPackageStatsObserver.Stub() {
     @Override
     public void onGetStatsCompleted(PackageStats packageStats, boolean succeeded) throws RemoteException {
      // TODO Auto-generated method stub
      Long cacheSize=packageStats.cacheSize;
      Long codeSize=packageStats.codeSize;
      Long dataSize=packageStats.dataSize;
      Long externalCacheSize=packageStats.externalCacheSize;
      Long externalCodeSize=packageStats.externalCodeSize;
      Long externalDataSize=packageStats.externalDataSize;
      Long externalMediaSize=packageStats.externalMediaSize;
      Long externalObbSize=packageStats.externalObbSize;
      System.out.println("cacheSize:" + Formatter.formatFileSize(getApplication(), cacheSize) + ",codeSize:" + Formatter.formatFileSize(getApplication(), codeSize) + ",dataSize:" + Formatter.formatFileSize(getApplication(), dataSize));
      System.out.println("externalCacheSize:" + Formatter.formatFileSize(getApplication(), externalCacheSize) + ",externalCodeSize:" + Formatter.formatFileSize(getApplication(), externalCodeSize) + ",externalDataSize:" + Formatter.formatFileSize(getApplication(), externalDataSize)+
        "externalMediaSize:"+Formatter.formatFileSize(getApplication(), externalMediaSize) + ",externalObbSize:" + Formatter.formatFileSize(getApplication(), externalObbSize) );
     String totalSize=Formatter.formatFileSize(getApplication(), (packageStats.cacheSize + packageStats.codeSize +packageStats.dataSize)/*/(1024*1024)*/);
     System.out.println((String) resolveInfo.loadLabel(pm)+"的总大小:" + totalSize /*+"M"*/);
     }
    });
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }

这个大小是和猎豹清理大师软件管理中的大小是一致的

点击item启动应用程序:

启动另外的一个应用程序的Activity:

http://www.apkbus.com/android-43480-1-1.html

http://gundumw100.iteye.com/blog/1138158  (其中这个比较好)

代码实现:

lv.setAdapter(adapter);

lv.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

String packageName = (String) items.get(position).get( "packageName");

//取到点击的包名

Intent i = pm.getLaunchIntentForPackage(packageName);

//如果该程序不可启动(像系统自带的包,有很多是没有入口的)会返回NULL

if (i != null)

startActivity(i);

}

});

转载于:https://my.oschina.net/u/1389206/blog/323661