日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android获取安装应用Apk包大小 缓存大小 getPackageSizeInfo StorageManager

發布時間:2024/8/1 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android获取安装应用Apk包大小 缓存大小 getPackageSizeInfo StorageManager 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

獲取安裝應用Apk包大小、緩存大小以及應用占用存儲總大小
可以通過 PackageManager類的getPackageSizeInfo方法獲取,但是這個方法被Google標記成隱藏方法,不能直接調用;
解決方法:可以通過反射調用,但在Android8.0及以上通過反射調用會報錯,不過Android8.0及以上可以通過StorageManager 獲取

Android8.0以下獲取Apk大小方法:
通過反射調用getPackageSizeInfo獲取

  • 創建AIDL文件
    • 創建文件 IPackageStatsObserver.aidl
    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
    package android.content.pm;parcelable PackageStats;

    注意包名路徑創建正確

    如下圖:

    創建完成后依次點擊 Build --> Make Project 以生成AIDL文件

  • 在AndroidManifest.xml 中添加權限
  • <uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
  • 代碼實現
  • public static void handlePackageSizeInfo(Context context, String packageName) {PackageManager mPackageManager = context.getPackageManager();Method getPackageSizeInfo = null;try {getPackageSizeInfo = mPackageManager.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);} catch (NoSuchMethodException e) {e.printStackTrace();}MyPackageStatsObserver mSecurityPackageStatsObserver = new MyPackageStatsObserver();if (getPackageSizeInfo != null) {try {getPackageSizeInfo.setAccessible(true);// 調用該函數,待調用完成后會回調MyPackageStatsObservergetPackageSizeInfo.invoke(mPackageManager, packageName, mSecurityPackageStatsObserver);} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {e.printStackTrace();}}}static class MyPackageStatsObserver extends IPackageStatsObserver.Stub {@Overridepublic void onGetStatsCompleted(PackageStats pStats, boolean succeeded) {long mCacheSize = pStats.cacheSize;long mCodeSize = pStats.codeSize;long mDataSize = pStats.dataSize;long mTotalSize = mCacheSize + mCodeSize + mDataSize;Log.d("AppLog", succeeded+ " cacheSize = " + mCacheSize + "; appSize = " + mCodeSize + "; " + "dataSize = " + mDataSize + "; totalSize = " + mTotalSize);}}

    Android8.0及以上獲取Apk大小方法:
    通過系統服務 StorageManager 獲取Apk大小,需要申請權限 PACKAGE_USAGE_STATS

  • 在AndroidManifest.xml 中添加權限
  • <uses-permissionandroid:name="android.permission.PACKAGE_USAGE_STATS"tools:ignore="ProtectedPermissions" />
  • 代碼實現
  • @RequiresApi(api = Build.VERSION_CODES.O)public static void getAppSize(Context context, String packageName){if (!hasUsageStatsPermission(context)){requestAppUsagePermission(context);} else {new Thread(() -> {final StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);final StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);final List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();final UserHandle user = android.os.Process.myUserHandle();try {for (StorageVolume storageVolume : storageVolumes) {final String uuidStr = storageVolume.getUuid();final UUID uuid = uuidStr == null ? StorageManager.UUID_DEFAULT : UUID.fromString(uuidStr);Log.d("AppLog", "storage:" + uuid + " : " + storageVolume.getDescription(context) + " : " + storageVolume.getState());Log.d("AppLog", "getFreeBytes:" + Formatter.formatShortFileSize(context, storageStatsManager.getFreeBytes(uuid)));Log.d("AppLog", "getTotalBytes:" + Formatter.formatShortFileSize(context, storageStatsManager.getTotalBytes(uuid)));StorageStats storageStats = storageStatsManager.queryStatsForPackage(uuid, packageName, user);Log.d("AppLog", "storage stats for app of package name:" + packageName + " : ");Log.d("AppLog", "getAppBytes:" + Formatter.formatShortFileSize(context, storageStats.getAppBytes()) + " getCacheBytes:" + Formatter.formatShortFileSize(context,storageStats.getCacheBytes()) + " getDataBytes:" + Formatter.formatShortFileSize(context, storageStats.getDataBytes()));}}catch (PackageManager.NameNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}).start();}}public static boolean hasUsageStatsPermission(Context context) {UsageStatsManager usageStatsManager = null;if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {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 2 minList<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 2 * 60 * 1000, currentTime);return stats != null && stats.size() > 0;}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) {Log.e("AppLog", "Start usage access settings activity fail!", e);}}

    總結

    public static void getInstallApkSize(Context context, String packageName){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {getAppSize(context, packageName);} else {handlePackageSizeInfo(context, packageName);}}

    Android8.0以下可以通過反射getPackageSizeInfo方法獲取Apk大小;
    Android8.0及以上可以通過申請權限 PACKAGE_USAGE_STATS 獲取其他已安裝應用的Apk大小
    還有一種比較復雜方法是 編譯一下的android2.3的Framework框架,把jar包拷出來,再把框架導入到library,之后就可以直接調用已經hide 的方法 getPackageSizeInfo() 了,具體操作可以搜一下

    總結

    以上是生活随笔為你收集整理的Android获取安装应用Apk包大小 缓存大小 getPackageSizeInfo StorageManager的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。