通过查看手机设置(setting)源代码,发现它里面获取应用大小和缓存大小是通过PackageManager里面的getPackageSizeInfo方法。然而此方法时私有的,因此通过反射调用此方法。里面要用到IPackageStatsObserver接口,它是一个aidl方式进行访问。

package cn.itcast.testclear;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import android.app.Activity;
import android.app.ListActivity;
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.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView; public class DemoActivity extends ListActivity {
private PackageManager pm;
private ListView lv;
private MyAdapter adapter; private Map<String, CacheInfo> maps; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pm = getPackageManager();
maps = new HashMap<String, CacheInfo>();
lv = getListView(); // lv.setAdapter(adapter); // 1.获取所有的安装好的应用程序 List<PackageInfo> packageinfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
for (PackageInfo info : packageinfos) {
String name = info.applicationInfo.loadLabel(pm).toString();
String packname = info.packageName;
CacheInfo cacheinfo = new CacheInfo();
cacheinfo.setName(name);
cacheinfo.setPackname(packname);
maps.put(packname, cacheinfo);
getAppSize(packname);
} adapter = new MyAdapter();
lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
/*
*
* <intent-filter> <action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" /> <category
* android:name="android.intent.category.DEFAULT" /> <data android:scheme="package" /> </intent-filter>
*/
/*
* 2.2 <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT"
* /> <category android:name="android.intent.category.VOICE_LAUNCH" /> </intent-filter>
*/
System.out.println("haha");
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addCategory("android.intent.category.VOICE_LAUNCH");
CacheInfo info = (CacheInfo) lv.getItemAtPosition(position);
intent.putExtra("pkg", info.getPackname());//传递所在包
startActivity(intent);
}
}); } /**
* 根据包名获取应用程序的体积信息 注意: 这个方法是一个异步的方法 程序的体积要花一定时间才能获取到.
*
* @param packname
*/
private void getAppSize(final String packname) {
try {
Method method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[]{String.class,
IPackageStatsObserver.class});
method.invoke(pm, new Object[]{packname,
new IPackageStatsObserver.Stub() {
public void onGetStatsCompleted(PackageStats pStats,boolean succeeded) throws RemoteException {
// 注意这个操作是一个异步的操作
long cachesize = pStats.cacheSize;
long codesize = pStats.codeSize;
long datasize = pStats.dataSize;
CacheInfo info = maps.get(packname);
info.setCache_size(TextFormater.getDataSize(cachesize));
info.setData_size(TextFormater.getDataSize(datasize));
info.setCode_size(TextFormater.getDataSize(codesize));
maps.put(packname, info); }
}}); } catch (Exception e) {
e.printStackTrace();
}
} private class MyAdapter extends BaseAdapter { private Set<Entry<String, CacheInfo>> sets;
private List<CacheInfo> cacheinfos; public MyAdapter() {
sets = maps.entrySet();
cacheinfos = new ArrayList<CacheInfo>();
for (Entry<String, CacheInfo> entry : sets) {
cacheinfos.add(entry.getValue());
} } public int getCount() {
return cacheinfos.size();
} public Object getItem(int position) {
return cacheinfos.get(position);
} public long getItemId(int position) {
return position;
} public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
CacheInfo info = cacheinfos.get(position);
if (convertView == null) {
view = View.inflate(DemoActivity.this, R.layout.item, null);
} else {
view = convertView;
}
TextView tv_cache_size = (TextView) view.findViewById(R.id.tv_cache_size);
TextView tv_code_size = (TextView) view.findViewById(R.id.tv_code_size);
TextView tv_data_size = (TextView) view.findViewById(R.id.tv_data_size);
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
tv_cache_size.setText(info.getCache_size());
tv_code_size.setText(info.getCode_size());
tv_data_size.setText(info.getData_size());
tv_name.setText(info.getName());
return view;
} } }
package cn.itcast.testclear;

public class CacheInfo {
//应用名称
private String name;
//应用所在包名
private String packname;
//
private String code_size;
//数据大小
private String data_size;
//缓存大小
private String cache_size;
}
public class TextFormater {

    /**
* 返回byte的数据大小对应的文本
*
* @param size
* @return
*/
public static String getDataSize(long size) {
if (size < 0) {
size = 0;
}
DecimalFormat formater = new DecimalFormat("####.00");
if (size < 1024) {
return size + "bytes";
} else if (size < 1024 * 1024) {
float kbsize = size / 1024f;
return formater.format(kbsize) + "KB";
} else if (size < 1024 * 1024 * 1024) {
float mbsize = size / 1024f / 1024f;
return formater.format(mbsize) + "MB";
} else if (size < 1024 * 1024 * 1024 * 1024) {
float gbsize = size / 1024f / 1024f / 1024f;
return formater.format(gbsize) + "GB";
} else {
return "size: error";
} } /**
* 返回kb的数据大小对应的文本
*
* @param size
* @return
*/
public static String getKBDataSize(long size) {
if (size < 0) {
size = 0;
}
return getDataSize(size * 1024);
}
}

aidl文件: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;

Android学习笔记_58_清除手机应用程序缓存的更多相关文章

  1. Android学习笔记_59_清除sdcard缓存

    对于手机来说,每个软件在安装时,都会在sdcard上创建一个目录,用于缓存文件.市场上针对这些软件,统一了它的sdcard上的目录,将缓存目录存放到数据库中.如果要清理,可以根据当前应用包的名称,到数 ...

  2. Android学习笔记36:使用SQLite方式存储数据

    在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...

  3. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  4. 【转】Pro Android学习笔记(三):了解Android资源(上)

    在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...

  5. 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期

    在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...

  6. Android学习笔记之滑动翻页(屏幕切换)

    如何实现手机上手动滑动翻页效果呢?呵呵,在这里我们就给你们介绍一下吧. 一般实现这个特效会用到一个控件:ViewFlipper <1>View切换的控件—ViewFlipper 这个控件是 ...

  7. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  8. Android学习笔记之Activity详解

    1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...

  9. 【转】 Pro Android学习笔记(七七):服务(2):Local Service

    目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...

随机推荐

  1. 数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11

    这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段.这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了. 这段代码,我用 ...

  2. Prestashop使用心得

    如果对Prestashop好奇的小伙伴快点进来看看吧,我开始接触了Prestashop这个开源的系统,这个一个非常棒的电商系统.因为我对这个Prestashop系统完全没有了解,但是上网却看不到太多的 ...

  3. QQ音乐:React v16 新特性实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由QQ音乐技术团队发表于云+社区专栏 自从去年9月份 React 团队发布了 v16.0 版本开始,到18年3月刚发布的 v16.3 版 ...

  4. 【卷土重来之C#学习笔记】(三) 类型 存储和变量

    .c#程序是一组类型声明 ※C#程序或DLL的源代码是一组一种或多种类型声明 ※对于可执行程序,类型声明必须有一个包含Main方法类 ※命名空间是一种把相关的类型声明分组并命名的方法.既然程序是一组相 ...

  5. Python编码规范杂记(很乱:))

    Python编码规范 导入模块 每一个(第三方)模块的导入都需要两个import语句, 如下 使用import some的方式导入模块, 如果有还有子模块的话, 则from father.son im ...

  6. Java入门系列-08-选择结构

    这篇文章为你搞懂2个问题 if-else选择结构的使用? switch 的使用? 前面我们学习的代码都是直上直下的执行,还不会"拐弯",这篇文章带大家来看一下会"拐弯&q ...

  7. BJFU 1551 ——delightful world——————【暴搜】

    delightful world 时间限制(C/C++):20000MS/30000MS          运行内存限制:65536KByte总提交:33            测试通过:10 描述 ...

  8. 04.Continue,和三元表达式的学习

    立即结束本次循环,判断循环条件,如果成立,则进入下一次循环,否则退出循环. 举例:运动员跑步喝水的例子 比如:我编写代码的时候,上个厕所,回来继续写代码 练习1: namespace _09.练习02 ...

  9. java.util.regex.Pattern正则表达式写验证器示例

    import java.util.regex.Pattern; /** * 校验器:利用正则表达式校验邮箱.手机号等 * */ public class Validator { /** * 正则表达式 ...

  10. [LeetCode]22. Generate Parentheses括号生成

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...