2012-01-10 91 views
2

我正在计算已安装应用程序的apk文件大小。这里是代码找到已安装应用程序的APK大小

public class PackageTabActivity extends ListActivity{ 

    private static final String APP_NAME = "app_name"; 
    private static final String APP_ICON = "app_icon"; 
    private static final String APP_SIZE = "app_size"; 
    Method getPackageSizeInfo = null; 
    PackageManager pm ; 
@Override 
public void onCreate(Bundle icicle){ 
    super.onCreate(icicle); 
    pm = getPackageManager(); 


    try { 
     getPackageSizeInfo = pm.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class); 
    } catch (SecurityException e1) { 

     e1.printStackTrace(); 
    } catch (NoSuchMethodException e1) { 

     e1.printStackTrace(); 
    } 
    new AppDetails().execute(); 
} 

private boolean isSystemPackage(PackageInfo pkgInfo) { 
    return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true 
      : false; 
} 


class AppDetails extends AsyncTask<Void, Void, ArrayList<HashMap<String , Object>>> 
{ 
    private long app_apk_size; 
    ProgressDialog mDialog; 
    @Override 
    public void onPreExecute() 
    { 
      mDialog = new ProgressDialog(PackageTabActivity.this); 
      mDialog.setCancelable(true); 
      mDialog.setMessage("Loading... "); 
      mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
      mDialog.setProgress(0); 
      mDialog.show(); 
    } 
    @Override 
    protected ArrayList<HashMap<String, Object>> doInBackground(
      Void... params) { 

     ArrayList<HashMap<String,Object>> applistwithicon = new ArrayList<HashMap<String,Object>>(); 
     HashMap<String,Object> hm; 
     String appname; 
     Drawable icon = null; 
     List<PackageInfo> packs = getPackageManager().getInstalledPackages(0); 

     for(int i=0;i<packs.size();i++) { 

      PackageInfo p = packs.get(i); 


      if(!isSystemPackage(p)) 
      { 
       hm = new HashMap<String, Object>(); 
       appname = p.applicationInfo.loadLabel(getPackageManager()).toString(); 

       icon = p.applicationInfo.loadIcon(getPackageManager()); 
       Log.v("package name", "package name =" + p.packageName); 
       try { 
        getPackageSizeInfo.invoke(pm, p.packageName, new IPackageStatsObserver.Stub() { 

        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { 

            app_apk_size = pStats.codeSize;  
            Log.v("apksize", "appsize = "+app_apk_size); 
        }   
      }); 
       }catch(IllegalAccessException e) {} 
       catch(IllegalArgumentException r) {} 
       catch(InvocationTargetException w){} 

      hm.put(APP_SIZE, (app_apk_size/(1024))); 
      hm.put(APP_ICON, icon); 
      hm.put(APP_NAME, appname); 
      applistwithicon.add(hm); 
      } 
     } 

     return applistwithicon; 
    } 
    @Override 
    public void onPostExecute(ArrayList<HashMap<String, Object>> result) 
    { 
     mDialog.dismiss(); 
     CustomAdapterList myAdapter = new CustomAdapterList(result,PackageTabActivity.this); 

      setListAdapter(myAdapter); 

    } 
} 
} 

这里IPackageStatsObserver是一个接口(aidl文件)。 这给了我模拟器上的正确结果,但在手机上。它给出了正确和错误的应用程序的大小。

我现在完全陷入困境,无法找到任何解决方法。

任何帮助将不胜感激。

+0

你能给有关不正确的结果更多的细节? 什么时候获得不正确的包装尺寸?在这里,你检查应用程序是否是系统软件包,如果是,绕过大小检查,为什么? 因为我曾经测试过系统应用codeSize并总是得到零。 我很好奇为什么系统应用codeSize不能总是被检索。是否有任何权限限制或其他原因? – user1391143 2012-05-12 14:20:49

+0

这里的问题是,应用程序的codeSize可能是在不同的线程计算。因此,使用'CountdownTimer'类,我们可以等待直到应用程序大小被计算。我不需要对系统应用做任何事情,所以我只是离开了他们。我不知道任何限制计算系统应用程序大小的权限。我们只需要GET_PACKAGE_SIZE权限来计算应用程序的大小。 – Sunny 2012-05-12 16:58:13

回答

0

这是来自Joseph为我工作的黑客。他原来的职位,可以发现here

PackageManager pm = getPackageManager(); 

Method getPackageSizeInfo = pm.getClass().getMethod(
    "getPackageSizeInfo", String.class, IPackageStatsObserver.class); 

getPackageSizeInfo.invoke(pm, "com.android.mms", 
    new IPackageStatsObserver.Stub() { 

     @Override 
     public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) 
      throws RemoteException { 

      Log.i(TAG, "codeSize: " + pStats.codeSize); 
     } 
    }); 
+0

请参阅我的代码,我已经使用过那个黑客。 – Sunny 2012-01-10 11:03:02

2
ApplicationInfo tmpInfo = context.getPackageManager().getApplicationInfo(packageName,-1); 
long size = new File(tmpInfo.sourceDir).length();