android 获取其他应用程序的缓存大小以及清理应用缓存
来源:互联网 发布:java字符串比较大小 编辑:程序博客网 时间:2024/05/23 15:44
最近在做appStore时,涉及到一个第三方app下载视频后将车机存储撑爆的问题,从而影响到我们车机自带的app使用,问题很是严重,于是就需要提供缓存清理以及垃圾清理的功能,当用户使用第三方app时,存储空间达到一定量的时候会提示用户去清理,否则不允许使用第三方app。
缓存获取
获取各个应用程序的缓存大小,可以通过使用PackageManager.getPackageSizeInfo方法来获取,但是它被隐藏了,所以我们只能通过反射来调用该方法
一、首先我们需要获取到系统中所有已安装app的基本信息
List<PackageInfo> installedPackages = mPackageManager.getInstalledPackages(0); for (PackageInfo packageInfo : installedPackages) { getCacheSize(packageInfo);//反射调用getPackageSizeInfo }
二、反射调用getPackageSizeInfo
/** * 获取到缓存的大小 * * @param packageInfo */ private void getCacheSize(PackageInfo packageInfo) { try { //通过反射获取到当前的方法 Method method = PackageManager.class.getDeclaredMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class); /** * 第一个参数表示当前的这个方法由谁调用的 * 第二个参数表示包名 */ method.invoke(mPackageManager, packageInfo.applicationInfo.packageName, new MyIPackageStatsObserver(packageInfo)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
三、调用getPackageSizeInfo需要两个参数,第一个参数是应用包名,通过packageInfo可以获取到,第二个参数是一个IPackageStatsObserver类型的回调,所有查询的结果都是从IPackageStatsObserver里面的onGetStatsCompleted方法里面回调回来的。onGetStatsCompleted是异步调用的,所以我们需要通过handler将结果更新到UI上.
public static final int HANDLER_UPDATE_CACHE_MSG = 0XF0F1; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (HANDLER_UPDATE_CACHE_MSG == msg.what) { if (msg.obj != null && msg.obj instanceof CacheInfo) { CacheInfo info = (CacheInfo) msg.obj; mCleanCacheAdapter.addDataAndRefresh(info); } } } }; private class MyIPackageStatsObserver extends IPackageStatsObserver.Stub { private PackageInfo packageInfo; public MyIPackageStatsObserver(PackageInfo packageInfo) { this.packageInfo = packageInfo; } @Override public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException { //获取到当前手机应用的缓存大小 long cacheSize = pStats.cacheSize;// 缓存大小 long dataSize = pStats.dataSize; // 数据大小 //如果当前的缓存大小大于0的话,则表示有缓存 if (cacheSize > 0) { CacheInfo cacheInfo = new CacheInfo(); Drawable icon = packageInfo.applicationInfo.loadIcon(mPackageManager); String appName = packageInfo.applicationInfo.loadLabel(mPackageManager).toString(); String packageName = packageInfo.packageName; cacheInfo.setAppName(appName); cacheInfo.setPackageName(packageName); cacheInfo.setIcon(icon); cacheInfo.setCacheSize(cacheSize); Message.obtain(mHandler, HANDLER_UPDATE_CACHE_MSG, cacheInfo).sendToTarget(); LogUtils.d(mTAG,"---读取缓存中------>" + cacheSize + "---cacheInfos.size()--" + mCacheInfos.size()); } } }
四、补充:注意点: IPackageStatsObserver.aidl和PackageStats.aidl文件都是从系统中拿出来的,需要放到指定的文件夹下(android.content.pm),否则会出现找不到的错误。上面的CacheInfo只是一个简单的javaBean用来存放每个应用所查询到的数据。
五、前面四步已经成功的将所有的app缓存大小都获取到了,接下来就是如何清理这些缓存,首先说说一键清理,就是一次性清理所有的缓存,可以调用PackageManager的freeStorageAndNotify的方法,同样还是@hide,所以我们依旧要通过反射来调用,直接前几步骤差不多直接看代码
public void cleanAll() { //获取到当前应用程序里面所有的方法 try { StatFs stat = new StatFs(Environment.getDataDirectory().getAbsolutePath()); Method mFreeStorageAndNotifyMethod = mPackageManager.getClass().getMethod( "freeStorageAndNotify", long.class, IPackageDataObserver.class); mFreeStorageAndNotifyMethod.invoke(mPackageManager, (long) stat.getBlockCount() * (long) stat.getBlockSize(), new MyIPackageDataObserver() ); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } class MyIPackageDataObserver extends IPackageDataObserver.Stub { public MyIPackageDataObserver() { } @Override public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException { LogUtils.e(mTAG,"当前清理的包名:"+packageName); if (succeeded){ LogUtils.e(mTAG,"清理成功!"); }else { LogUtils.e(mTAG,"清理失败!"); } } }
前面那些操作所需要的权限:
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" /> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
六、到此为止,我所查询到的资料基本都是这些步骤,如果需要单独清理的应用数据的话,大都是直接跳到系统清理界面,通过系统操作清理。不过我们车机很显然不可能跳到系统界面然后清理,所以只能另寻他路,后来查到ActivityManager:clearApplicationUserData这个方法,是用于应用清除用户数据,相当于在设置中清除应用数据,同样也是隐藏的所以我们还是通过反射来调用,具体代码就不提供了,跟上面方式是一样的。
七、然后第六步操作之后运行会直接挂掉,提示缺少android.permission.CLEAR_APP_USER_DATA权限,然而加上之后还是会挂掉,还是提示缺少这个权限,也就是说普通的app我们是无法获取到这个权限的,所以我们还需要在AndroidManifest.xml里面配置android:sharedUserId=”android.uid.system”,这句配置的意思就是获取系统的进程权限,然后我们的app还需要调用系统平台的签名,这样就能单独的清理指定应用的缓存数据了。其实这个有很大的缺陷,由于应用和系统签名是绑定在一起的,所以这个应用只能在指定的系统上安装,其他的系统是安装不了的,我们车机系统是自己定制的,所以这个方式,对我这个应用来说是没问题的。
- android 获取其他应用程序的缓存大小以及清理应用缓存
- 获取缓存的大小 以及清理缓存
- android获取缓存大小并清理缓存
- android获取缓存大小并清理缓存
- 获取缓存的大小并且清理缓存
- 获取APP缓存大小以及清理APP缓存
- Android开发——获取应用数据/缓存大小并清理缓存
- Android应用数据、缓存的清除和获取缓存大小
- iOS 计算缓存大小以及清理缓存
- Android 清理应用缓存
- Android 清理应用缓存
- android---清理应用缓存
- Android 清理应用缓存
- android获取应用程序大小,缓存数据信息
- 98利用反射清理应用程序的缓存以及清理所有应用程序的缓存
- iOS 缓存,以及缓存大小,缓存清理等
- 清理app应用程序的缓存
- iOS 获取应用程序缓存大小
- (1)Linux的初步了解
- 低延时的RTMP网络直播
- python自然语言处理 第四章基本语法
- maven-assembly-plugin打包插件配置
- 20年程序员的碎碎念
- android 获取其他应用程序的缓存大小以及清理应用缓存
- 二维码好高大尚,我也想生成一个
- 加固+多渠道打包+Bugly统计+热修复
- ACM (4) ASCII码排序
- hibernate使用MySQLInnoDBDialect不能自动建表的问题
- 【Java并发】- 使用CompletionService异步收集任务结果
- 2,3,5,6,6,6
- 第二个重要极限的证明 e怎么出来的
- 多版本中文停用词词表 + 多版本英文停用词词表 + python词表合并程序