2012-01-10 2 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 - это интерфейс (файл helpl). Это дает мне правильный результат на эмуляторе, но на телефоне. Он дает смесь правильного и неправильного размера приложения.

Я сейчас полностью застрял и не нашел никакого обходного пути.

Любая помощь была бы высоко оценена.

+0

Не могли бы вы дать более подробную информацию о некорректном результате? Когда появляется неправильный размер пакета? Здесь вы проверяете, является ли приложение системным пакетом, если да, обходите проверку размера, почему? Как я когда-либо тестировал системный код приложения, и всегда получал ZERO. Мне очень любопытно, почему системный код приложения codeSize не всегда можно получить. Есть ли ограничение на разрешение или другая причина? – user1391143

+0

Здесь проблема заключалась в том, что codeSize приложения может быть рассчитан в разных потоках. Поэтому, используя класс CountdownTimer, мы можем подождать, пока не будет рассчитан размер приложения. Мне не нужно было ничего делать с системным приложением, поэтому я просто оставил их. Я не знаю о каких-либо разрешениях, которые ограничивают вычисление размера системного приложения. Для вычисления размера приложения требуется только разрешение GET_PACKAGE_SIZE. – Sunny

ответ

0

Вот хак от Иосифа, который работал на меня. Его оригинальный пост можно найти 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

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

 Смежные вопросы

  • Нет связанных вопросов^_^