Reputation: 941
How can I get the size of an app, including the size of the AppData?
At the moment I use this code, but it just gets the APK size. Is there any way to get the size of the AppData, like the Google Setting App does it?
public String getApkSize(Context context, String packageName) {
try {
float value = new File(context.getPackageManager().getApplicationInfo(packageName, 0).publicSourceDir).length() / 1048576F;
if (value <= 0) {
value = 1;
}
return String.format("%.2f", value) + "MB";
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
Upvotes: 4
Views: 2012
Reputation: 623
Unfortunately there is no official way to do so. The following relies on reflections so runtime errors could be around the corner.
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);
}
});
Careful since this is a hack trying to fulfill a missing part of the Android SDK.
Upvotes: 0
Reputation: 32780
The Settings app uses the method getPackageSizeInfo
. Unfortunately this method is hidden because it is annotated with @hide
, for this reason you can't directly use the method, but you need to use reflection to invoke it.
Add this permission to the AndroidManifest.xml
:
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
Create the AIDL interface IPackageStatsObserver
:
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);
}
Then you can use it like this:
private void getPackageSizeInfo(Context context, String packageName) {
try {
PackageManager packageManager = context.getPackageManager();
Method getPackageSizeInfo = packageManager.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
getPackageSizeInfo.invoke(packageManager, packageName, new IPackageStatsObserver.Stub() {
public void onGetStatsCompleted(PackageStats packageStats, boolean succeeded) throws RemoteException {
long totalCacheSize = packageStats.cacheSize + packageStats.externalCacheSize;
long totalDataSize = packageStats.dataSize + packageStats.externalDataSize;
long totalCodeSize = packageStats.codeSize + packageStats.externalCodeSize;
long totalSize = totalDataSize + totalCodeSize;
Log.d(TAG, "Total Size:" + totalSize);
Log.d(TAG, "App Size:" + totalCodeSize);
Log.d(TAG, "Data Size:" + totalDataSize);
Log.d(TAG, "Cache Size:" + totalCacheSize);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
Upvotes: 5