通过查看手机设置(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. JDK7之HashMap源码

    并发场景下使用HashMap的问题分析:疫苗:Java HashMap的死循环 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6423457 ...

  2. java集合常用操作

    收集一些常用集合操作的代码,用于治疗健忘症,:) set转list //构造Map数据 Map<String, String> map = new HashMap<String, S ...

  3. xss攻击汇总--转

    (1)普通的XSS JavaScript注入<SCRIPT SRC=http://3w.org/XSS/xss.js></SCRIPT>(2)IMG标签XSS使用JavaScr ...

  4. HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】

    Can you answer these queries? Time Limit:2000MS     Memory Limit:65768KB     64bit IO Format:%I64d & ...

  5. Druid手动创建连接的坑

    环境:druid 1.1.10 今天优化了一天的代码, 老代码手动创建连接,坑 Connection conn = DBUtil.getConnection("d_log_dot_" ...

  6. C#异步编程模型

    什么是异步编程模型 异步编程模型(Asynchronous Programming Model,简称APM)是C#1.1支持的一种实现异步操作的编程模型,虽然已经比较“古老”了,但是依然可以学习一下的 ...

  7. C#中三个关键字params,Ref,out

    关于这三个关键字之前可以研究一下原本的一些操作 using System; using System.Collections.Generic; using System.Text; namespace ...

  8. CSP学习之导出密钥BLOB 解析

    通过CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, NULL, &dwBlobLen) 函数导出的公钥信息如下: 06 02 00 00 00 A4 ...

  9. express 请求跨域后端解决方法CORS

    CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源. Origin表示本域,也就是浏览器当前页面的域.当JavaScript向外域(如sin ...

  10. js带文字的圆随机运动

    首先是html代码(其实就只有一个画布,记得要把外部js引入写在body底部 <!doctype html> <html> <head> <meta http ...