Android学习笔记_58_清除手机应用程序缓存

通过查看手机设置(setting)源代码,发现它里面获取应用大小和缓存大小是通过PackageManager里面的getPackageSizeInfo方法。然而此方法时私有的,因此通过反射调用此方法。里面要用到IPackageStatsObserver接口,它是一个aidl方式进行访问。

package cn.itcast.testclear;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class DemoActivity extends ListActivity {
    private PackageManager pm;
    private ListView lv;
    private MyAdapter adapter;

    private Map<String, CacheInfo> maps;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        pm = getPackageManager();
        maps = new HashMap<String, CacheInfo>();
        lv = getListView();

        // lv.setAdapter(adapter);

        // 1.获取所有的安装好的应用程序

        List<PackageInfo> packageinfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
        for (PackageInfo info : packageinfos) {
            String name = info.applicationInfo.loadLabel(pm).toString();
            String packname = info.packageName;
            CacheInfo cacheinfo = new CacheInfo();
            cacheinfo.setName(name);
            cacheinfo.setPackname(packname);
            maps.put(packname, cacheinfo);
            getAppSize(packname);
        }

        adapter = new MyAdapter();
        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                /*
                 * 
                 * <intent-filter> <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" /> <category
                 * android:name="android.intent.category.DEFAULT" /> <data android:scheme="package" /> </intent-filter>
                 */
                /*
                 * 2.2 <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT"
                 * /> <category android:name="android.intent.category.VOICE_LAUNCH" /> </intent-filter>
                 */
                System.out.println("haha");
                Intent intent = new Intent();
                intent.setAction("android.intent.action.VIEW");
                intent.addCategory("android.intent.category.DEFAULT");
                intent.addCategory("android.intent.category.VOICE_LAUNCH");
                CacheInfo info = (CacheInfo) lv.getItemAtPosition(position);
                intent.putExtra("pkg", info.getPackname());//传递所在包
                startActivity(intent);
            }
        });

    }

    /**
     * 根据包名获取应用程序的体积信息 注意: 这个方法是一个异步的方法 程序的体积要花一定时间才能获取到.
     * 
     * @param packname
     */
    private void getAppSize(final String packname) {
        try {
            Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[]{String.class,
                            IPackageStatsObserver.class});
            method.invoke(pm, new Object[]{packname,
                    new IPackageStatsObserver.Stub() {
                        public void onGetStatsCompleted(PackageStats pStats,boolean succeeded) throws RemoteException {
                            // 注意这个操作是一个异步的操作
                            long cachesize = pStats.cacheSize;
                            long codesize = pStats.codeSize;
                            long datasize = pStats.dataSize;
                            CacheInfo info = maps.get(packname);
                            info.setCache_size(TextFormater.getDataSize(cachesize));
                            info.setData_size(TextFormater.getDataSize(datasize));
                            info.setCode_size(TextFormater.getDataSize(codesize));
                            maps.put(packname, info);

                        }
                    }});

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class MyAdapter extends BaseAdapter {

        private Set<Entry<String, CacheInfo>> sets;
        private List<CacheInfo> cacheinfos;

        public MyAdapter() {
            sets = maps.entrySet();
            cacheinfos = new ArrayList<CacheInfo>();
            for (Entry<String, CacheInfo> entry : sets) {
                cacheinfos.add(entry.getValue());
            }

        }

        public int getCount() {
            return cacheinfos.size();
        }

        public Object getItem(int position) {
            return cacheinfos.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view = null;
            CacheInfo info = cacheinfos.get(position);
            if (convertView == null) {
                view = View.inflate(DemoActivity.this, R.layout.item, null);
            } else {
                view = convertView;
            }
            TextView tv_cache_size = (TextView) view.findViewById(R.id.tv_cache_size);
            TextView tv_code_size = (TextView) view.findViewById(R.id.tv_code_size);
            TextView tv_data_size = (TextView) view.findViewById(R.id.tv_data_size);
            TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
            tv_cache_size.setText(info.getCache_size());
            tv_code_size.setText(info.getCode_size());
            tv_data_size.setText(info.getData_size());
            tv_name.setText(info.getName());
            return view;
        }

    }

}
package cn.itcast.testclear;

public class CacheInfo {
    //应用名称
    private String name;
    //应用所在包名
    private String packname;
    //
    private String code_size;
    //数据大小
    private String data_size;
    //缓存大小
    private String cache_size;
}
public class TextFormater {

    /**
     * 返回byte的数据大小对应的文本
     * 
     * @param size
     * @return
     */
    public static String getDataSize(long size) {
        if (size < 0) {
            size = 0;
        }
        DecimalFormat formater = new DecimalFormat("####.00");
        if (size < 1024) {
            return size + "bytes";
        } else if (size < 1024 * 1024) {
            float kbsize = size / 1024f;
            return formater.format(kbsize) + "KB";
        } else if (size < 1024 * 1024 * 1024) {
            float mbsize = size / 1024f / 1024f;
            return formater.format(mbsize) + "MB";
        } else if (size < 1024 * 1024 * 1024 * 1024) {
            float gbsize = size / 1024f / 1024f / 1024f;
            return formater.format(gbsize) + "GB";
        } else {
            return "size: error";
        }

    }

    /**
     * 返回kb的数据大小对应的文本
     * 
     * @param size
     * @return
     */
    public static String getKBDataSize(long size) {
        if (size < 0) {
            size = 0;
        }
        return getDataSize(size * 1024);
    }
}

aidl文件:IPackageStatsObserver.aidl

/*
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

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

/* //device/java/android/android/view/WindowManager.aidl
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

package android.content.pm;

parcelable PackageStats;
原文地址:https://www.cnblogs.com/lbangel/p/3584489.html