《笔记》Android 获取第三方应用及查看应用信息、apk大小、缓存、存储,以及第三方清除缓存
获取应用相关信息:
PS:manifest标签中设置以下属性表示系统应用
android:process="system" android:sharedUserId="android.uid.system"
//获取所有应用(非系统apk,有些应用获取不到)
List<ApplicationInfo> installedApplications = getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);
获取缓存,apk体积,存储大小,版本号等:
//全局变量,保存当前查询包得信息
private long cachesize ; //缓存大小
private long datasize ; //数据大小
private long codesize ; //应用程序大小
private long totalsize ; //总大小
//获取相关数据
public void queryPacakgeSize() {
getPackageSizeInfo(new PackageStatsObserver());
}
/**
* 8.0及以下回调使用
* */
private class PackageStatsObserver extends IPackageStatsObserver.Stub {
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
Log.d("hsh", "packageName = "+pStats.packageName+"---"+(pStats.cacheSize + pStats.externalCacheSize));
// 在此处理 PackageStats 数据
// TODO Auto-generated method stub
cachesize = pStats.cacheSize ; //缓存大小
datasize = pStats.dataSize ; //数据大小
codesize = pStats.codeSize ; //应用程序大小
totalsize = cachesize + datasize + codesize ;
// Log.i("hsh", "cachesize--->"+cachesize+" datasize---->"+datasize+ " codeSize---->"+codesize) ;
setViewData();
}
}
/**
* 获取apk体积,内存,缓存信息
* */
private void getPackageSizeInfo( IPackageStatsObserver.Stub observer) {
Context context = SettingApplication.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
final StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
final StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
try {
StorageStats storageStats = storageStatsManager.queryStatsForPackage(applicationInfo.storageUuid,applicationInfo.packageName, UserHandle.getUserHandleForUid(applicationInfo.uid));
// StorageStats storageStats = storageStatsManager.queryStatsForUid(applicationInfo.storageUuid, applicationInfo.uid);
cachesize = storageStats.getCacheBytes();//缓存大小
datasize = storageStats.getDataBytes();//数据大小
codesize = storageStats.getAppBytes();//应用程序大小
totalsize = cachesize + datasize + codesize ;
// Log.i("hsh", "packageName:"+this.applicationInfo+",,"+cachesize + ",," + datasize + ",," + codesize+",,"+totalsize);
setViewData();
} catch (Exception e) {
e.printStackTrace();
}
} else {
//9.0及以上此方法无效,会抛出错误
try {
Method method = pm.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
method.invoke(pm, this.applicationInfo.packageName, observer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void setViewData(){
try {
ApplicationInfo app = mContext.getPackageManager().getApplicationInfo(this.applicationInfo.packageName, 0);
PackageInfo packageInfo = pm.getPackageInfo(app.packageName, PackageManager.GET_SIGNATURES);
//赋值缓存
tvAppCacheData.setText(formateFileSize(datasize));
//有些apk获取不到内存大小,所以通过file.length()去获取
if (!TextUtils.isEmpty(applicationInfo.sourceDir)) {
File file = new File(applicationInfo.sourceDir);
tvAppMemoryData.setText(formateFileSize(file.length()));//赋值apk大小
} else {
tvAppMemoryData.setText(formateFileSize(codesize));
}
//获取版apk其他应用消息,比如说版本versionCode,versionName等
tvAppVersionCode.setText(packageInfo.versionName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
//系统函数,字符串转换 long -String (kb)
private String formateFileSize(long size){
return Formatter.formatFileSize(mContext, size);
}
清除缓存,通过反射deleteApplicationCacheFiles清除缓存数据,看了下没什么效果改成clearApplicationUserData后测试可以:
public void deleteDir(String packageName) {
try {
Method method = pm.getClass().getMethod(
"clearApplicationUserData",
String.class,
IPackageDataObserver.class
);
// 指定目标应用包名(如 com.example.app)
method.invoke(pm, packageName, new IPackageDataObserver.Stub() {
@Override
public void onRemoveCompleted(String pkg, boolean success) {
// 清理完成回调
Log.i(TAG, "onRemoveCompleted: "+pkg+"====="+success);
ToastUtil.s(R.string.str_clear_cache);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
PS:查看底层代码发现8.0以后被强制抛出异常