45、系统优化--代码实现

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;

全书阅毕!

代码已经整理并上传到CSDN资源:http://download.csdn.net/detail/asmcvc/6885709

工程最好是用android studio打开。

你可能感兴趣的:(45、系统优化--代码实现)