Import java.lang.reflect.InvocationTargetException;
Import Java.lang.reflect.Method;
Import java.util.List;
Import android.app.Activity;
Import android.content.Intent;
Import Android.content.pm.ApplicationInfo;
Import Android.content.pm.IPackageDataObserver;
Import Android.content.pm.IPackageStatsObserver;
Import Android.content.pm.PackageInfo;
Import Android.content.pm.PackageManager;
Import android.content.pm.PackageManager.NameNotFoundException;
Import Android.content.pm.PackageStats;
Import Android.net.Uri;
Import Android.os.Bundle;
Import android.os.RemoteException;
Import Android.text.format.Formatter;
Import Android.view.View;
Import Android.view.View.OnClickListener;
Import Android.widget.ImageView;
Import Android.widget.LinearLayout;
Import Android.widget.ProgressBar;
Import Android.widget.TextView;
Import Android.widget.Toast;
public class Cleancacheactivity extends Activity {
Private TextView Tv_scan_status;
Private ProgressBar PB;
Private Packagemanager pm;
Private LinearLayout Ll_container;
Private Boolean flag = false;
Private long totalcleansize = 0;
Private long Tempcache;
Private View Romoveview;
Private Boolean Isexitscache = true;
Private Method Getpackagesizeinfomethod = null; Methods of API hiding
Private String Cleanpackgename; To clean up the cached package name
Private toast Toast;
@Override
protected void OnCreate (Bundle savedinstancestate) {
TODO auto-generated Method Stub
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_clean_cache);
Tv_scan_status = (TextView) Findviewbyid (r.id.tv_scan_status);
PB = (ProgressBar) Findviewbyid (R.ID.PB);
Ll_container = (linearlayout) Findviewbyid (R.id.ll_container);
Scancache ();
}
/**
* Scan all the app's cache information inside the phone
*/
private void Scancache () {
PM = Getpackagemanager ();
New Thread () {
public void Run () {
1. Find the method that gets the cache first (this method is hidden by the API.) So first get the byte code of the class. Re-reflection)
Method[] methods = PackageManager.class.getMethods ();
for (Method method:methods) {
if ("Getpackagesizeinfo". Equals (Method.getname ())) {
Getpackagesizeinfomethod = method;
Break
}
}
2. Use this method in each application to get all the cache files
list<packageinfo> Packinfos = pm.getinstalledpackages (0);
Pb.setmax (Packinfos.size ());
int progress = 0;
for (PackageInfo Packinfo:packinfos) {
try {
Getpackagesizeinfomethod.invoke (PM, Packinfo.packagename, New Mydataobserver ()); Running in a child thread
Thread.Sleep (200);
progress++;
Pb.setprogress (progress);
} catch (Exception e) {
E.printstacktrace ();
}
}
if (Progress >= packinfos.size ()) {
Runonuithread (New Runnable () {
@Override
public void Run () {
Tv_scan_status.settext ("Scan complete ...");
}
});
}
All scans complete without a cache found
if (flag = = False) {
Runonuithread (New Runnable () {
public void Run () {
String Text = "Congratulations on your mobile phone is very clean." No cache required to clean up ";
Showtoast (text);
Tv_scan_status.settext ("Scan complete. No cache found ");
}
});
}
};
}.start ();
}
Note that the method of this parent class is run in a child thread, so to update the UI interface, the main thread
Private class Mydataobserver extends ipackagestatsobserver.stub{
@Override
public void ongetstatscompleted (Final Packagestats pstats, Boolean succeeded)
Throws RemoteException {
Final long cache = Pstats.cachesize;
Final ApplicationInfo AppInfo;
try {
AppInfo = Pm.getapplicationinfo (pstats.packagename, 0);
Update interface
Runonuithread (New Runnable () {
@Override
public void Run () {
Tv_scan_status.settext ("Scanning" +appinfo.loadlabel (PM). toString ());
if (Cache > 0) {//app with cached information
Flag = true;//There is a cache file
Totalcleansize + = cache;
Final View view = View.inflate (Getapplicationcontext (), r.layout.list_item_cacheinfo, NULL);
TextView tv_cache_size = (TextView) View.findviewbyid (r.id.tv_cache_size);
Tv_cache_size.settext ("Cache Size:" +
Formatter.formatfilesize (Getapplicationcontext (), cache));
TextView tv_name = (TextView) View.findviewbyid (r.id.tv_app_name);
Tv_name.settext (Appinfo.loadlabel (PM). toString ());
ImageView Iv_icon = (ImageView) View.findviewbyid (R.id.iv_app_icon);
Iv_icon.setimagedrawable (Appinfo.loadicon (PM));
ImageView Iv_clean = (ImageView) View.findviewbyid (R.id.iv_clean);
Iv_clean.setonclicklistener (New Onclicklistener () {
@Override
public void OnClick (View v) {
Tempcache = cache;
Cleanpackgename = Appinfo.packagename;
Romoveview = view;
Intent Intent = new Intent ();
Intent.setaction ("Android.settings.APPLICATION_DETAILS_SETTINGS");
Intent.addcategory ("Android.intent.category.DEFAULT");
Intent.setdata (Uri.parse ("package:" + cleanpackgename));
Startactivityforresult (Intent, 0);
}
});
Ll_container.addview (view, 0);
}
}
});
} catch (Namenotfoundexception e) {
TODO auto-generated Catch block
E.printstacktrace ();
}
}
}
Please note that. The method of this parent class is run in a child thread. So to update the UI interface, the main thread
Private class MyDataObserver2 extends ipackagestatsobserver.stub{
@Override
public void ongetstatscompleted (Final Packagestats pstats, Boolean succeeded)
Throws RemoteException {
Isexitscache = false;
System.out.println (pstats.cachesize);
if (Pstats.cachesize > 0) {//There is also a cache
Isexitscache = true;
}
}
}
@Override
protected void Onactivityresult (int requestcode, int resultcode, Intent data) {
Another query once to see if the cache has been cleaned
try {
Getpackagesizeinfomethod.invoke (PM, Cleanpackgename, New MyDataObserver2 ()); Running in a child thread
Thread.Sleep (200);
} catch (Exception e) {
E.printstacktrace ();
}
if (Isexitscache) {
}else{//This cache is no longer present, update interface
String Text = "Freed" +formatter.formatfilesize (Getapplicationcontext (), Tempcache) + "Memory space";
Showtoast (text);
Ll_container.removeview (Romoveview);
}
Super.onactivityresult (Requestcode, ResultCode, data);
}
Please note that. The method of this parent class is run in a child thread, so to update the UI interface, the main thread
Private class Mypackdataobserver extends ipackagedataobserver.stub{
@Override
public void onremovecompleted (String PackageName, Boolean succeeded)
Throws RemoteException {
Runonuithread (New Runnable () {
@Override
public void Run () {
Ll_container.removeallviews ();
String Text = "Freed" + formatter.formatfilesize (Getapplicationcontext (), totalcleansize) +
"Memory space \ n Congratulations on your mobile phone is very clean, no cache need to clean up";
Showtoast (text);
totalcleansize = 0;
Tv_scan_status.settext ("Cache cleanup complete");
}
});
}
}
/**
* Clean up all the cache on your phone
* Freestorageandnotify () is a system-hidden API, so use reflection to find it
* @param view
*/
public void Cleanall (view view) {
Method[] methods = PackageManager.class.getMethods ();
for (Method method:methods) {
if ("Freestorageandnotify". Equals (Method.getname ())) {
try {
Method.invoke (PM, Integer.max_value, New Mypackdataobserver ());
} catch (Exception e) {
E.printstacktrace ();
}
}
}
}
private void Showtoast (String text) {
if (toast = = null) {
Toast = Toast.maketext (Getapplicationcontext (), text, 0);
}else{
Toast.settext (text);
Toast.setduration (0);
}
Toast.show ();
}
}
Android gets a small fragment of the cache file code for each application (using AIDL)