如何以编程方式计算已安装应用程序的所有缓存大小?

Posted

技术标签:

【中文标题】如何以编程方式计算已安装应用程序的所有缓存大小?【英文标题】:How to programmatically calculate all cache size of installed application? 【发布时间】:2015-04-09 01:49:43 【问题描述】:

我只想显示所有已安装应用程序名称和缓存大小的列表。缓存大小必须与android设备中的原生设置应用程序显示相同。

我能够列出所有已安装的应用程序 pkg 名称,但无法计算本机设置应用程序显示的相同缓存大小(我说的是设置中清除缓存选项的地方)。

pkNames = getPackageManager().getInstalledPackages(0);

                    ArrayAdapter<PackageInfo> adapter = new ArrayAdapter<PackageInfo>(this,
                            android.R.layout.simple_list_item_1, pkNames);
                     final PackageManager pm = getPackageManager();
                    for(int i =0;i<pkNames.size();i++)
                    
                        ApplicationInfo applicationInfo = pm.getApplicationInfo(pkNames.get(i).packageName.toString(), 0);
                        File file = new File(applicationInfo.publicSourceDir);
                        long size = file.length();
                        System.out.println("application name == "+pkNames.get(i).packageName.toString()+"  ,and size of cache is == "+size(this, size));
                     

我使用此代码,但它会给我该应用程序的 .apk 大小。 :( 请帮忙 提前致谢。

【问题讨论】:

请查看答案 我查过但无法理解你的答案 你试过代码了吗?因为它对我有用..它正在计算已安装应用程序的缓存大小...... 是的,但在活动中,“IDataStatus”类在哪里,“IPackageStatsObserver.class”在哪里,你尝试扩展的 IPackageStatsObserver.Stub 是什么。我应该在这个项目中包含任何库 不,它不需要任何库或任何东西......通过将 IPackageStatsObserver.aidl 文件添加到提到的包中它应该可以工作 【参考方案1】:

在以下路径中找到应用程序缓存文件夹到内存中

"/data/data/com.your.package.appname/cache"

计算磁盘上的应用程序缓存大小。

【讨论】:

【参考方案2】:

直接获取已安装应用程序的缓存大小是无法获取的。 由于使用PackageManger,我们无法直接获取有关已安装包大小的详细信息,因为抽象getPackageSizeInfo 方法无法直接访问,因此使用Java Reflection 您可以调用它。如果将来方法名称更改或任何事情,它可能无法正常工作改变了。

您需要创建 AIDL IPackageStatsObserver.aidl & PackageStats.aidl,它们应该在 android.content.pm 包中,因为您无法直接访问它们。

IPackageStatsObserver.aidl

package android.content.pm;
import android.content.pm.PackageStats;
oneway interface IPackageStatsObserver 
void onGetStatsCompleted(in android.content.pm.PackageStats pStats, boolean succeeded);

PackageStats.aidl

package android.content.pm;
parcelable PackageStats;

IPackageStatsObserver.aidl 和 PackageStats.aidl 都保存在 android.content.pm 包中。 IDataStatus

public interface IDataStatus 
    public void onStatusListner(String msg);

活动

    public class MyScreen extends Activity implements OnClickListener 
    public static final int FETCH_PACKAGE_SIZE_COMPLETED = 100;
    public static final int ALL_PACAGE_SIZE_COMPLETED = 200;
    IDataStatus onIDataStatus;
    TextView lbl_cache_size;
    ProgressDialog pd;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.btn_get_cacheSize).setOnClickListener(this);
        lbl_cache_size = (TextView) findViewById(R.id.lbl_cache_size);
        // clearCache();
    

    private void showProgress(String message) 
        pd = new ProgressDialog(this);
        pd.setIcon(R.drawable.ic_launcher);
        pd.setTitle("Please Wait...");
        pd.setMessage(message);
        pd.setCancelable(false);
        pd.show();

    

    long packageSize = 0, size = 0;
    AppDetails cAppDetails;
    public ArrayList<PackageInfoStruct> res;

    private void getpackageSize() 
        cAppDetails = new AppDetails(this);
        res = cAppDetails.getPackages();
        if (res == null)
            return;
        for (int m = 0; m < res.size(); m++) 
            PackageManager pm = getPackageManager();
            Method getPackageSizeInfo;
            try 
                getPackageSizeInfo = pm.getClass().getMethod(
                        "getPackageSizeInfo", String.class,
                        IPackageStatsObserver.class);
                getPackageSizeInfo.invoke(pm, res.get(m).pname,
                        new cachePackState());
             catch (SecurityException e) 
                e.printStackTrace();
             catch (NoSuchMethodException e) 
                e.printStackTrace();
             catch (IllegalArgumentException e) 
                e.printStackTrace();
             catch (IllegalAccessException e) 
                e.printStackTrace();
             catch (InvocationTargetException e) 
                e.printStackTrace();
            

        
        handle.sendEmptyMessage(ALL_PACAGE_SIZE_COMPLETED);
        Log.v("Total Cache Size", " " + packageSize);

    

    private Handler handle = new Handler() 
        @Override
        public void handleMessage(Message msg) 
            switch (msg.what) 
            case FETCH_PACKAGE_SIZE_COMPLETED:
                if (packageSize > 0)
                    size = (packageSize / 1024000);
                lbl_cache_size.setText("Cache Size : " + size + " MB");
                break;
            case ALL_PACAGE_SIZE_COMPLETED:
                if (null != pd)
                    if (pd.isShowing())
                        pd.dismiss();

                break;
            default:
                break;
            

        

    ;

    private class cachePackState extends IPackageStatsObserver.Stub 

        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                throws RemoteException 
            Log.d("Package Size", pStats.packageName + "");
            Log.i("Cache Size", pStats.cacheSize + "");
            Log.w("Data Size", pStats.dataSize + "");
            packageSize = packageSize + pStats.cacheSize;
            Log.v("Total Cache Size", " " + packageSize);
            handle.sendEmptyMessage(FETCH_PACKAGE_SIZE_COMPLETED);
        

    

    @Override
    public void onClick(View v) 
        switch (v.getId()) 
        case R.id.btn_get_cacheSize:
            size = 0;
            packageSize = 0;
            showProgress("Calculating Cache Size..!!!");
            /**
             * You can also use async task
             * */
            new Thread(new Runnable() 

                @Override
                public void run() 
                    getpackageSize();
                
            ).start();

            break;
        
    


应用详情

public class AppDetails 
    Activity mActivity;
    public ArrayList<PackageInfoStruct> res = new ArrayList<PackageInfoStruct>();
    public ListView list;
    public String app_labels[];

    public AppDetails(Activity mActivity) 
        this.mActivity = mActivity;

    

    public ArrayList<PackageInfoStruct> getPackages() 
        ArrayList<PackageInfoStruct> apps = getInstalledApps(false); /*
                                                                     * false =
                                                                     * no system
                                                                     * packages
                                                                     */
        final int max = apps.size();
        for (int i = 0; i < max; i++) 
            apps.get(i);
        
        return apps;
    

    private ArrayList<PackageInfoStruct> getInstalledApps(boolean getSysPackages) 

        List<PackageInfo> packs = mActivity.getPackageManager()
                .getInstalledPackages(0);
        try 
            app_labels = new String[packs.size()];
         catch (Exception e) 
            Toast.makeText(mActivity.getApplicationContext(), e.getMessage(),
                    Toast.LENGTH_SHORT).show();
        
        for (int i = 0; i < packs.size(); i++) 
            PackageInfo p = packs.get(i);
            if ((!getSysPackages) && (p.versionName == null)) 
                continue;
            
            PackageInfoStruct newInfo = new PackageInfoStruct();
            newInfo.appname = p.applicationInfo.loadLabel(
                    mActivity.getPackageManager()).toString();
            newInfo.pname = p.packageName;
            newInfo.datadir = p.applicationInfo.dataDir;
            newInfo.versionName = p.versionName;
            newInfo.versionCode = p.versionCode;
            newInfo.icon = p.applicationInfo.loadIcon(mActivity
                    .getPackageManager());
            res.add(newInfo);

            app_labels[i] = newInfo.appname;
        
        return res;
    

    class PackageInfoStruct 
        String appname = "";
        String pname = "";
        String versionName = "";
        int versionCode = 0;
        Drawable icon;
        String datadir = "";
    

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical" >

  <Button
        android:id="@+id/btn_get_cacheSize"
        android:layout_
        android:layout_
        android:text="Get Cache Size" />

    <TextView
        android:id="@+id/lbl_cache_size"
        android:layout_
        android:layout_
        android:text="Cache Size : " />

</LinearLayout>

【讨论】:

是的...但我想知道缓存后台进程的状态...我怎样才能做到这一点.... 其实我想知道应用后台缓存的进程和他们使用的进程大小。 IDataStatus 是aidl文件还是简单的界面 @Nepster 它的界面很简单 @Nepster for theaidl 我已经提到了扩展名为 .aidl 的文件名

以上是关于如何以编程方式计算已安装应用程序的所有缓存大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式获取已安装的防病毒软件和防火墙?

IOS如何防止下载的图片以编程方式缓存

如何以编程方式清空浏览器缓存?

如何以编程方式访问 iOS 中其他已安装应用程序的 info.plist?

以编程方式获取已安装的应用程序详细信息以打开 pdf

以编程方式获取 Windows 中所有已安装更新的列表