[mobilesafe] 06_通过系统隐藏的api获取缓存,清理缓存

Android 4.0

通过系统隐藏的api获取缓存,清理缓存

PackageManager隐藏下的api,只能通过反射来获取 1、获取缓存
public abstract void getPackageSizeInfo(String packageName,
            IPackageStatsObserver observer);
public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageStatsObserver
{ }
权限:  <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />  
//Stub是一个内部类,它实现了Binder,实现了 
IPackageStatsObserver
2、清理缓存
public abstract void deleteApplicationCacheFiles(String packageName,
            IPackageDataObserver observer);
权限: <uses-permission android:name="android.permission.DELETE_CACHE_FILES"/>
注意:只有系统应用,才能声明此权限,不能给第三方应用声明该权限
Not for use by third-party applications. 
所以,这里的一键清理功能不能实现,因为此应用不是系统应用
核心代码:
package cn.zengfansheng.getCacheSize;
 
import java.lang.reflect.Method;
 
import android.app.Activity;
import android.content.Context;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.format.Formatter;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
    private EditText et_package;
    private TextView tv_cache;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        et_package = (EditText) this.findViewById(R.id.et_package);
        tv_cache = (TextView) this.findViewById(R.id.tv_cache);
    }
 
    /**
     * 2、1清除缓存
     * @param view
     */

    public void cleanCache(View view){
        // mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver);
        // class ClearCacheObserver extends IPackageDataObserver.Stub
        PackageManager packageManager = getPackageManager();
        try {
            String packageName = et_package.getText().toString();
 
            Method method = PackageManager.class.getMethod("deleteApplicationCacheFiles",String.class, IPackageDataObserver.class);
            method.invoke(packageManager, packageName,new MyClearCacheObserver());
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 2、2清理缓存的远程服务实现类-一键清理缓存
     * @author hacket
     */

    private class MyClearCacheObserver extends IPackageDataObserver.Stub {
 
        @Override
        public void onRemoveCompleted(String packageName, boolean succeeded)
                throws RemoteException {
        }
    }
 
 
    /**
     * 1、1获取缓存-扫描缓存
     * @param view
     */

    public void getCache(View view) {
 
        // ApplicationPackageManager ap;//隐藏的类
        PackageManager pm = this.getPackageManager();
        /*
         PackageManager隐藏的api
         @hide
         public abstract void getPackageSizeInfo(String packageName,
            IPackageStatsObserver observer);
         */

        try {
            String packageName = et_package.getText().toString();
            Method method = PackageManager.class.getMethod("getPackageSizeInfo", String.class,IPackageStatsObserver.class);
 
            method.invoke(pm, packageName, new MyIPackageStatsbserver());
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 1、2清除缓存的远程服务实现类
     * @author hacket
     */

    private class MyIPackageStatsbserver extends IPackageStatsObserver.Stub {
        // onGetStatsCompleted在另外的一个线程获取的数据. 所以不能直接更新ui
        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                throws RemoteException {
            long cacheSize = pStats.cacheSize;
            long codeSize = pStats.codeSize;
            long dataSize = pStats.dataSize;
            Context context = getApplicationContext();
            final String cache = Formatter.formatFileSize(getApplicationContext(), cacheSize);
            final String code = Formatter.formatFileSize(getApplicationContext(), codeSize);
            final String data = Formatter.formatFileSize(context, dataSize);
 
            System.out.println("缓存大小:" + cache + "代码大小:" + code + "数据大小:"+ data);
 
            // 子线程中更新ui
            runOnUiThread(new Thread() {
                public void run() {
                    tv_cache.setText("缓存大小:"+cache+"代码大小:"+code+"数据大小:"+data);
                }
            });
        }
    }
}