参考链接:https://stackoverflow.com/questions/49606077/android-packagestats-gives-always-zero
简单来说,就是我代码里面用的反射的方法获取应用大小,但是会报Shame on you for calling the hidden API getPackageSizeInfoAsUser(). Shame!的异常信息,查询之后发现是api26以下可以用反射的这种方法,但是26以上会报错
解决方法参见链接
api<26 就是我项目里是这样写的
Method method = getMethod("getPackageSizeInfo");
for (int i = 0; i < packages.size(); i++) {
ApplicationInfo pkg = packages.get(i);
if (Build.VERSION.SDK\_INT < Build.VERSION\_CODES.O) {
try {
method.invoke(pm, pkg.packageName, new IPackageStatsObserver.Stub() {
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
if (succeeded) {
ArrayList<AppsListItem> listItems = mAppsMapItem.get(pStats.packageName);
for (AppsListItem appsListItem:listItems){
appsListItem.mDataSize = pStats.dataSize;
appsListItem.mCacheSize = pStats.cacheSize;
appsListItem.mCodeSize = pStats.codeSize;
}
if (index >= packages.size()) {
index = 0;
} else {
index++;
}
lock.lock();
try {
count++;
if (count >= packages.size()) {
Message msg = myHandler.obtainMessage();
msg.what = INSTALL;
myHandler.sendMessage(msg);
index = 0;
}
} catch (Exception e) {
}
lock.unlock();
}
}
});
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();//api 26以上会走这里
}
api大于26的时候可以用以下代码(根据实际使用更改,下面的是我代码里面的),
@SuppressLint("WrongConstant") final StorageStatsManager storageStatsManager = (StorageStatsManager)getSystemService(Context.STORAGE_STATS_SERVICE); final StorageManager storageManager = (StorageManager)getSystemService(Context.STORAGE_SERVICE); try { ApplicationInfo ai = getPackageManager().getApplicationInfo(pkg.packageName, 0); StorageStats storageStats = storageStatsManager.queryStatsForUid(ai.storageUuid, pkg.uid); ArrayList<AppsListItem> listItems = mAppsMapItem.get(pkg.packageName); for (AppsListItem appsListItem : listItems) { appsListItem.mDataSize = storageStats.getDataBytes(); appsListItem.mCacheSize = storageStats.getCacheBytes(); appsListItem.mCodeSize = storageStats.getAppBytes(); } // Log.d("zjw", mAppsListItem.get(index).mPackageName + "//" + pStats.packageName); if (index >= packages.size()) { index = 0; } else { index++; } lock.lock(); try { count++; if (count >= packages.size()) { Message msg = myHandler.obtainMessage(); msg.what = INSTALL; myHandler.sendMessage(msg); index = 0; } } catch (Exception e) { } lock.unlock(); } catch (Exception e) { e.printStackTrace(); }
需要 USAGE ACCESS PERMISSION 权限,申请权限如下
清单文件里面:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
代码里面:
public static boolean checkAppUsagePermission(Context context) { UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); if(usageStatsManager == null) { return false; } long currentTime = System.currentTimeMillis(); // try to get app usage state in last 1 min List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 60 * 1000, currentTime); if (stats.size() == 0) { return false; } return true; } public static void requestAppUsagePermission(Context context) { Intent intent = new Intent(android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { context.startActivity(intent); } catch (ActivityNotFoundException e) { e.printStackTrace(); } }