Android学习笔记_58_清除手机应用程序缓存
通过查看手机设置(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_清除手机应用程序缓存的更多相关文章
- Android学习笔记_59_清除sdcard缓存
对于手机来说,每个软件在安装时,都会在sdcard上创建一个目录,用于缓存文件.市场上针对这些软件,统一了它的sdcard上的目录,将缓存目录存放到数据库中.如果要清理,可以根据当前应用包的名称,到数 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- 【转】Pro Android学习笔记(三十):Menu(1):了解Menu
目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...
- 【转】Pro Android学习笔记(三):了解Android资源(上)
在Android开发中,资源包括文件或者值,它们和执行应用捆绑,无需在源代码中写死,因此我们可以改变或替换他们,而无需对应用重新编译. 了解资源构成 参考阅读Android学习笔记(三八):资源res ...
- 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期
在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...
- Android学习笔记之滑动翻页(屏幕切换)
如何实现手机上手动滑动翻页效果呢?呵呵,在这里我们就给你们介绍一下吧. 一般实现这个特效会用到一个控件:ViewFlipper <1>View切换的控件—ViewFlipper 这个控件是 ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- 【转】 Pro Android学习笔记(七七):服务(2):Local Service
目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...
随机推荐
- C++ Memory System Part3 : 优化
前面的系列我们讲了自定义new和delete操作,其中针对deleteArray的问题还有需要优化的地方.我们这次就针对POD类型进行一次优化. 下面的代码是针对POD类型的模板函数实现,分别为New ...
- ElasticSearch mapping中字段属性总结
- QQ音乐:React v16 新特性实践
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由QQ音乐技术团队发表于云+社区专栏 自从去年9月份 React 团队发布了 v16.0 版本开始,到18年3月刚发布的 v16.3 版 ...
- jQuery对新添加的控件添加响应事件
1. 通过id和类控制 <html> <head> <script src="jquery.js"></script> <sc ...
- 线程中断方法interrupt() 与 cancel()
(一).关于interrupt() interrupt()并不直接中断线程,而是设定一个中断标识,然后由程序进行中断检查,确定是否中断. 1. sleep() & interr ...
- 引爆你的Javascript代码进化 (转)
转自 海玉的博客 方才在程序里看到一段JS代码,写法极为高明,私心想着若是其按照规范来写,定可培养对这门语言的理解,对JS编程能力提高必是极好的.说人话:丫代码写的太乱,看的窝火! 最近闲暇无事,准备 ...
- R语言计算相关矩阵然后将计算结果输出到CSV文件
R语言计算出一个N个属性的相关矩阵(),然后再将相关矩阵输出到CSV文件. 读入的数据文件格式如下图所示: R程序采用如下语句: data<-read.csv("I:\\SB\land ...
- 用C#实现工资计算公式动态编写
1,工资计算公式 每一个企业都一定会用到工资计算,发工资是一件非常神圣的事情,而计算工资就是一项非常重要的工作.Excel有非常强大的公式功能,帮助了很多财务人员计算工资,但如果企业的人数比较多,而且 ...
- Js 对象数组,转化为字符串
var str = [{"cuid":"23910","content":"是","type":&q ...
- 删除排序数组中的重复数字 - C++
class Solution { public: /** * @param A: a list of integers * @return : return an integer */ int rem ...