Android擷取各個應用程式的快取檔案代碼小片段(使用AIDL)

來源:互聯網
上載者:User

標籤:run   setimage   tostring   listen   ddc   art   raw   view   class   

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;  //API隱藏的方法
private String cleanPackgename ; //要清理緩衝的包名
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();
}




/**
* 掃描手機裡面全部應用程式的緩衝資訊
*/
private void scanCache() {
pm = getPackageManager();
new Thread(){
public void run() {

//1.先找到擷取緩衝的方法(這種方法是被API隱藏起來的。所以要先擷取類的位元組碼。再反射)

Method[] methods = PackageManager.class.getMethods();
for(Method method : methods){
if("getPackageSizeInfo".equals(method.getName())){
getPackageSizeInfoMethod = method;
break;
}
}

//2.在每個應用程式中使用該方法擷取全部的快取檔案
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()); //子線程中運行
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("掃描完成...");
}
});
}
//所有掃描完成沒有發現一個緩衝
if(flag == false){
runOnUiThread( new Runnable() {
public void run() {

String text =  "恭喜您手機非常乾淨。沒有緩衝須要清理";
showToast(text);
tv_scan_status.setText("掃描完成。沒發現緩衝");
}
});
}

};
}.start();

}

//請注意,這個父類的方法是在子線程中啟動並執行,所以要更新UI介面的話,要在主線程
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);

//更新介面
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_scan_status.setText("正在掃描"+appInfo.loadLabel(pm).toString());
if(cache > 0){  //有緩衝資訊的應用
flag = true;//存在快取檔案
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("緩衝大小: "+ 
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();
}
}

}

//請注意。這個父類的方法是在子線程中啟動並執行。所以要更新UI介面的話,要在主線程
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){   //還存在緩衝
isExitsCache = true;
}
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

//又一次查詢一次看是否緩衝已被清理
try {
getPackageSizeInfoMethod.invoke(pm, cleanPackgename, new MyDataObserver2());  //子線程中運行
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}

if(isExitsCache){

}else{   //此緩衝已經不存在了,更新介面
String text =  "釋放了"+Formatter.formatFileSize(getApplicationContext(), tempCache)+"的記憶體空間";
showToast(text);
ll_container.removeView(romoveview);
}

super.onActivityResult(requestCode, resultCode, data);
}

//請注意。這個父類的方法是在子線程中啟動並執行,所以要更新UI介面的話,要在主線程
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 = "釋放了"+ Formatter.formatFileSize(getApplicationContext(), totalCleanSize)+
"的記憶體空間\n恭喜您手機非常乾淨,沒有緩衝須要清理";
showToast(text);
totalCleanSize = 0;
tv_scan_status.setText("緩衝清理完成");
}
});
}

}

/**
* 清理手機的所有緩衝
* freeStorageAndNotify() 為系統隱藏的API,所以要用反射把它找出來
* @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擷取各個應用程式的快取檔案代碼小片段(使用AIDL)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.