1. 程式人生 > >查詢手機已安裝應用大小,適配 android 8

查詢手機已安裝應用大小,適配 android 8

一、查詢手機所有已安裝的應用

可以通過 PackageManager 來獲取,可以使用


PackageManager pm = context.getPackageManager();
List<ApplicationInfo> apps = pm.getInstalledApplications(0);

//或者
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER)
; List<ResolveInfo> apps = pm.queryIntentActivities(intent,0);

遍歷即可獲取所有應用的包名,圖示、版本等等資訊,但不包括應用大小,如程式碼、資料、快取資訊。

二、 在 Android O 之前版本

獲取應用本身大小可以通過 PackageManager 的隱藏函式 getPackageSizeInfo(String packageName, IPackageStatsObserver observer) ,利用反射來獲取,簡單示例程式碼如下,注意獲取是通過AIDL進行,所以需要在工程中建立 IPackageStatsObserver.aidl

PackageStats.aidl 檔案

PackageManager pm = context.getPackageManager();
Method method = null;
try {
	//反射獲取函式
    method = PackageManager.class.getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
} catch (NoSuchMethodException e) {
    error = OTHER_ERROR;
}

if(method!=null)
{ try { //呼叫反射 method.invoke(pm, info.packageName, packageStatsObserver); } catch (IllegalAccessException e) { e.printStackTrace(); error = OTHER_ERROR; } catch (InvocationTargetException e) { e.printStackTrace(); error = OTHER_ERROR; } }

最後,在 IPackageStatsObserver 中回撥更新資料

IPackageStatsObserver packageStatsObserver = new IPackageStatsObserver.Stub() {
	@Override
	public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {  
		long codeBytes = pStats.codeSize;
		long dataBytes = pStats.dataSize;
		long cacheBytes = pStats.cacheSize;
	}
};

三、 在 Android O 之後

系統提供了一個儲存類來解析已安裝應用包,這就是 StorageStatsManager , 通過提供的 public @NonNull StorageStats queryStatsForPackage(@NonNull UUID storageUuid,@NonNull String packageName, @NonNull UserHandle user)

傳入應用 uuid 或者使用預設 StorageManager.UUID_DEFAULT,查詢的應用包名,可以直接查詢應用的安裝資訊。
注意:
* 使用適用在 android O 及之後版本
* 需要使用者許可權 android.permission.PACKAGE_USAGE_STATS
* 該許可權使用 context.requestPermission(...) 可能無效,需要引導使用者到設定中開啟

示例程式碼如下:


StorageStatsManager statsManager = (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
UserHandle handler = UserHandle.getUserHandleForUid(-2);

try{
	StorageStats stats = statsManager.queryStatsForPackage(StorageManager.UUID_DEFAULT, info.packageName, handler);
	long codeBytes = stats.getAppBytes();
	long dataBytes = stats.getDataBytes();
	long cacheBytes = stats.getCacheBytes();
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (SecurityException e) {
    //這裡說明沒有許可權,沒有許可權只能查詢自身應用大小
    e.printStackTrace();
}

當沒有許可權 android.permission.PACKAGE_USAGE_STATS 時,引導使用者到設定頁面設定

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
context.startActivity(intent);

執行截圖:

  1. android 8:

    • 有許可權 PACKAGE_USAGE_STATS
      執行截圖
    • 無許可權 PACKAGE_USAGE_STATS
      執行截圖
  2. android 5
    執行截圖

四、 結尾

這裡關於應用大小的查詢就結束了,通過 PackageManager 還可以清理手機快取,更多的使用,可以查閱原始碼。

附註:

完整程式碼可以戳我查閱 ->> 完整程式碼

Demo 示例查閱 ->> Demo