我正在试图弄清楚如何获得已安装应用的大小.
什么已经失败:
- new File('/data/app/some.apk')报告不正确的大小
- PackageManager.getPackageSizeInfo(String packageName, IPackageStatsObserver observer)- @hide并依赖于一些模糊IPackageStatsObserver的结果,所以我不能通过反射调用它.
Jos*_*ger 27
不幸的是,目前没有正式的方法可以做到这一点.但是,如果将aID 和AIDL导入到项目中并生成存根,则可以调用PackageManager隐藏getPackageSize方法.然后,您可以使用反射来调用:PackageStatsIPackageStatsObservergetPackageSize
PackageManager pm = getPackageManager();
Method getPackageSizeInfo = pm.getClass().getMethod(
"getPackageSizeInfo", String.class, IPackageStatsObserver.class);
getPackageSizeInfo.invoke(pm, "com.android.mms",
new IPackageStatsObserver.Stub() {
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
throws RemoteException {
Log.i(TAG, "codeSize: " + pStats.codeSize);
}
});
Run Code Online (Sandbox Code Playgroud)
这显然是一个大黑客,不应该用于公共应用程序.
kra*_*iec 19
你可以通过gettting到apk文件的路径,并检查其长度来简化:
final PackageManager pm = context.getPackageManager();
ApplicationInfo applicationInfo = pm.getApplicationInfo(appInfo.getPackage(), 0);
File file = new File(applicationInfo.publicSourceDir);
int size = file.length();
Run Code Online (Sandbox Code Playgroud)
以下是@Josef Pfleger的补充答案,以征求意见
"我发现某些设备没有getPackageSizeInfo()然后你得到这个java.lang.NoSuchMethodException:getPackageSizeInfo()"@ ATom 11月29日11:15.
在api 16(Build.VERSION.SDK_INT> 16)之后,该方法
PackageManager.getPackageSizeInfo(String packageName, IPackageStatsObserver observer);
Run Code Online (Sandbox Code Playgroud)
改变成:
PackageManager.getPackageSizeInfo(String packageName, int userHandle, IPackageStatsObserver observer);
Run Code Online (Sandbox Code Playgroud)
并且新添加的参数的解释userHandle是:应该检索其大小信息的用户.
所以我们应该这样做:
int sysVersion= Build.VERSION.SDK_INT;
if (pkgName != null) {// packageName
PackageManager pm = getPackageManager();
try {
Class<?> clz = pm.getClass();
if (sysVersion>16) {
Method myUserId=UserHandle.class.getDeclaredMethod("myUserId");//ignore check this when u set ur min SDK < 17
int userID = (Integer) myUserId.invoke(pm);
Method getPackageSizeInfo = clz.getDeclaredMethod(
"getPackageSizeInfo", String.class,int.class,
IPackageStatsObserver.class);//remember add int.class into the params
getPackageSizeInfo.invoke(pm,pkgName, userID, new PkgSizeObserver());
} else {//for old API
Method getPackageSizeInfo = clz.getDeclaredMethod(
"getPackageSizeInfo", String.class,
IPackageStatsObserver.class);
getPackageSizeInfo.invoke(pm, pkgName, new PkgSizeObserver());
}
} catch (Exception ex) {
Log.e(TAG, "NoSuchMethodException");
ex.printStackTrace();
throw ex;}
Run Code Online (Sandbox Code Playgroud)
该类需要回调如下:
private class PkgSizeObserver extends IPackageStatsObserver.Stub {
/***
* @param pStatus
* @param succeeded
*/
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
throws RemoteException {
cachesize = pStats.cacheSize;//remember to declare these fields
datasize = pStats.dataSize;
codesize = pStats.codeSize;
totalsize = cachesize + datasize + codesize;
Log.i("123","cachesize--->" + cachesize + " datasize---->"
+ datasize + " codeSize---->" + codesize);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用此方法来解析long2string,然后你可以看到xx MB而不是long像2342334 :)
private String formateFileSize(long size) {
return Formatter.formatFileSize(MainActivity.this, size);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23154 次 |
| 最近记录: |