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);
}
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;
全书阅毕!
代码已经整理并上传到优快云资源:http://download.youkuaiyun.com/detail/asmcvc/6885709
工程最好是用android studio打开。