CleanCacheActivity代码:
package com.example.mobilesafe; import android.app.Activity; 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.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.text.format.Formatter; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by sing on 14-1-26. * desc: */ public class CleanCacheActivity extends Activity { public static final int ADD_ONE_RESULT = 1; // 显示扫描的进度 private ProgressBar pd; // 提示扫描的状态 private TextView tv_clean_cache_status; // 系统的包管理器 private PackageManager pm; // 显示所有带有缓存的应用程序信息 private LinearLayout ll_clean; // 存放缓存信息 private Map<String, Long> cacheinfo; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case ADD_ONE_RESULT: //扫描到一条 final String packname = (String) msg.obj; // 获取这些应用程序的图标,名称,展现在界面上。 View child = View.inflate(getApplicationContext(), R.layout.cache_item, null); // 为child注册一个监听器。 child.setOnClickListener(new View.OnClickListener() { // 点击child时响应的点击事件 @Override public void onClick(View v) { // 判断SDK的版本号 if (Build.VERSION.SDK_INT >= 9) { // 跳转至“清理缓存”的界面(可以通过:设置-->应用程序-->点击任意应用程序后的界面) Intent intent = new Intent(); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(Uri.parse("package:" + packname)); startActivity(intent); } else { Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.addCategory("android.intent.category.VOICE_LAUNCH"); intent.putExtra("pkg", packname); startActivity(intent); } } }); // 为child中的控件设置数据 ImageView iv_icon = (ImageView) child.findViewById(R.id.iv_cache_icon); iv_icon.setImageDrawable(getApplicationIcon(packname)); TextView tv_name = (TextView) child.findViewById(R.id.tv_cache_name); tv_name.setText(getApplicationName(packname)); TextView tv_size = (TextView) child.findViewById(R.id.tv_cache_size); tv_size.setText("缓存大小 :" + Formatter.formatFileSize(getApplicationContext(), cacheinfo.get(packname))); // 将child添加到ll_clean控件上。 ll_clean.addView(child); break; } } ; }; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cleancache_layout); pd = (ProgressBar) findViewById(R.id.progressBar1); ll_clean = (LinearLayout) findViewById(R.id.ll_clean_cache_cont); tv_clean_cache_status = (TextView) findViewById(R.id.tv_clean_cache_status); pm = getPackageManager(); scanPackages(); } // 扫描出带有缓存的应用程序 private void scanPackages() { // 开启一个异步任务扫描带有缓存的应用程序 new AsyncTask<Void, Integer, Void>() { // 存储手机中所有已安装的应用程序的包信息 List<PackageInfo> packinfos; @Override protected Void doInBackground(Void... params) { int i = 0; for (PackageInfo info : packinfos) { // 获取到应用程序的包名信息 String packname = info.packageName; getSize(pm, packname); i++; try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } publishProgress(i); } return null; } @Override protected void onPreExecute() { cacheinfo = new HashMap<String, Long>(); packinfos = pm.getInstalledPackages(0); pd.setMax(packinfos.size()); tv_clean_cache_status.setText("开始扫描..."); super.onPreExecute(); } @Override protected void onPostExecute(Void result) { tv_clean_cache_status.setText("扫描完毕..." + "发现有" + cacheinfo.size() + "个缓存信息"); super.onPostExecute(result); } @Override protected void onProgressUpdate(Integer... values) { pd.setProgress(values[0]); tv_clean_cache_status.setText("正在扫描" + values[0] + "条目"); super.onProgressUpdate(values); } }.execute(); } // 通过反射的方式调用packageManager中的方法 private void getSize(PackageManager pm, String packname) { try { // 获取到getPackageSizeInfo。调用getPackageSizeInfo方法需要在清单文件中配置权限信息:<uses-permission // android:name="android.permission.GET_PACKAGE_SIZE"/> Method method = pm.getClass().getDeclaredMethod("getPackageSizeInfo", new Class[]{String.class, IPackageStatsObserver.class}); // 执行getPackageSizeInfo方法 method.invoke(pm, new Object[]{packname, new MyObersver(packname)}); } catch (Exception e) { e.printStackTrace(); } } // 执行packageManager中的getPackageSizeInfo方法时需要传入IPackageStatsObserver.Stub接口,该接口通过aidl调用。 private class MyObersver extends IPackageStatsObserver.Stub { private String packname; public MyObersver(String packname) { this.packname = packname; } @Override public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { // 以下是根据ApplicationsState代码中的SizeInfo对象中定义的 // 缓存大小 long cacheSize = pStats.cacheSize; // 代码大小 long codeSize = pStats.codeSize; // 数据的大小 long dataSize = pStats.dataSize; // 判断这个包名对应的应用程序是否有缓存,如果有,则存入到集合中。 if (cacheSize > 0) { Message msg = Message.obtain(); msg.what = ADD_ONE_RESULT; msg.obj = packname; handler.sendMessage(msg); cacheinfo.put(packname, cacheSize); } } } // 获取到应用程序的名称 private String getApplicationName(String packname) { try { PackageInfo packinfo = pm.getPackageInfo(packname, 0); return packinfo.applicationInfo.loadLabel(pm).toString(); } catch (Exception e) { e.printStackTrace(); return packname; } } // 获取到应用程序的图标 private Drawable getApplicationIcon(String packname) { try { PackageInfo packinfo = pm.getPackageInfo(packname, 0); return packinfo.applicationInfo.loadIcon(pm); } catch (Exception e) { e.printStackTrace(); return getResources().getDrawable(R.drawable.ic_launcher); } } }
获取缓存大小调用了PackageManager的隐藏函数getPackageSizeInfo:
// 通过反射的方式调用packageManager中的方法 private void getSize(PackageManager pm, String packname) { try { // 获取到getPackageSizeInfo。调用getPackageSizeInfo方法需要在清单文件中配置权限信息:<uses-permission // android:name="android.permission.GET_PACKAGE_SIZE"/> Method method = pm.getClass().getDeclaredMethod("getPackageSizeInfo", new Class[]{String.class, IPackageStatsObserver.class}); // 执行getPackageSizeInfo方法 method.invoke(pm, new Object[]{packname, new MyObersver(packname)}); } catch (Exception e) { e.printStackTrace(); } }
清单文件需要添加权限:
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
清理缓存调用系统的缓存清理功能:
// 为child注册一个监听器。 child.setOnClickListener(new View.OnClickListener() { // 点击child时响应的点击事件 @Override public void onClick(View v) { // 判断SDK的版本号 if (Build.VERSION.SDK_INT >= 9) { // 跳转至“清理缓存”的界面(可以通过:设置-->应用程序-->点击任意应用程序后的界面) Intent intent = new Intent(); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(Uri.parse("package:" + packname)); startActivity(intent); } else { Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.addCategory("android.intent.category.VOICE_LAUNCH"); intent.putExtra("pkg", packname); startActivity(intent); } } });另外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); }
/* //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;
全书阅毕!
代码已经整理并上传到CSDN资源:http://download.csdn.net/detail/asmcvc/6885709
工程最好是用android studio打开。