通过查看手机设置(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. java泛型中的各种限制

    java和其他语言一样,都支持泛型,包括泛型类和泛型方法,但是java的泛型比较特殊.因为java的泛型并不是在java诞生之初就加入的,在很长的一段时间里,java是没有泛型的,在需要泛型的地方,统 ...

  2. 数据库和AI的一次火花

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由宗文 发表于云+社区专栏 | 导语 通过历史数据,基于时间序列来预测未来. 我们生活中很多数据是有时间维度的.比如说天气或者股票价格. ...

  3. React.js 小书 Lesson15 - 实战分析:评论功能(二)

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson15 转载请注明出处,保留原文链接和作者信息. 上一节我们构建了基本的代码框架,现在开始完善其 ...

  4. BNU27932——Triangle——————【数学计算面积】

    Triangle Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class nam ...

  5. avalon实现分页组件

    前言 分页组件比较常见,但是用avalon实现的见的不多,这个分页组件,可以适配2种分页方式, 第一种是每次点击下一页,就请求一次后台,并返回当页数据和总条数,我称之为假分页: 第二种是一次性把所有数 ...

  6. c#-IO和序列化操作

    IO 用到的命名空间:using System.IO; 文件和目录的管理! File类 FileInfo类 Directory类 DirectoryInfo类 操作文件的类! FileStream{ ...

  7. solidity数据类型

    1.Bool类型 取值:true/false 运算符:!  && || == != 2.Integer整型 uint8-uint256 int8-int256 uint == uint ...

  8. Fragment中的方法findFragmentById(int id)的返回值探讨

    在学习<Android编程权威指南>P124页的时候,遇到了这样的代码: 引起了我的疑问if的判断条件是(fragment==null),那执行完上一句 Fragment Fragment ...

  9. 最新机动车行驶证模板PSD可编辑分层文件下载

    机动车行驶证PSD模板下载地址: http://www.qijieworld.com/thread-1834752-1-1.html 模板为psd格式,内容可编辑修改,需使用 Photoshop CS ...

  10. 靠谱的div引入任何外链内容

    靠谱的div引入任何外链内容 开发中经常要在div中引入一个页面,该页面可能是内部页面,可能是一个外部页面,也可能只是一个域名获取的请求. 对于内部页面的加载,建议使用jquery的load函数,如: ...