其他分享
首页 > 其他分享> > 如何在Android O上使用StorageStatsManager.queryStatsForPackage?

如何在Android O上使用StorageStatsManager.queryStatsForPackage?

作者:互联网

背景

在使用Android O之前,为了获得应用程序的大小,您必须具有特殊的权限,并使用隐藏的API.

问题

这样的解决方案不再起作用,但是Google提供了一个不太细粒度的官方API:queryStatsForPackage,它返回StorageStats对象.

但是,我找不到有关如何使用它的任何信息.

与仅需要应用程序包名称的隐藏API相比,该API还需要“ String volumeUuid”和“ UserHandle user”.

问题

>如何提供这些参数?
>这是什么意思?每个volumeUuid是否引用不同的存储(例如,内置存储和真实的SD卡),而UserHandle是针对每个用户的吗?
>如果#2是正确的,我是否应该为每个可能的值分别调用它们,以获取应用程序占用的实际总存储量?如果是这样,怎么办?

解决方法:

好的,我已经找到了如何使用新的API.我为此准备了一个小样本,以获取有关卷存储和特定应用程序的一些信息(这次是Play商店,但您可以根据需要进行更改):

public class MainActivity extends AppCompatActivity {

    public static final String PACKAGE_NAME = "com.android.vending";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!hasUsageStatsPermission(this))
            startActivityForResult(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY), 1);
        else {
            final Context context = this;
            AsyncTask.execute(new Runnable() {
                @TargetApi(VERSION_CODES.O)
                @Override
                public void run() {
                    @SuppressLint("WrongConstant") final StorageStatsManager storageStatsManager = (StorageStatsManager) getSystemService(Context.STORAGE_STATS_SERVICE);
                    final StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
                    final List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
                    final UserHandle user = Process.myUserHandle();
                    for (StorageVolume storageVolume : storageVolumes) {
                        final String uuidStr = storageVolume.getUuid();
                        final UUID uuid = uuidStr == null ? StorageManager.UUID_DEFAULT : UUID.fromString(uuidStr);
                        try {
                            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)));
                            Log.d("AppLog", "storage stats for app of package name:" + PACKAGE_NAME + " : ");

                            final StorageStats storageStats = storageStatsManager.queryStatsForPackage(uuid, PACKAGE_NAME, user);
                            Log.d("AppLog", "getAppBytes:" + Formatter.formatShortFileSize(context, storageStats.getAppBytes()) +
                                    " getCacheBytes:" + Formatter.formatShortFileSize(context, storageStats.getCacheBytes()) +
                                    " getDataBytes:" + Formatter.formatShortFileSize(context, storageStats.getDataBytes()));
                        } catch (NameNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });

        }
    }

    @TargetApi(VERSION_CODES.M)
    public static boolean hasUsageStatsPermission(Context context) {
        //https://stackoverflow.com/a/42390614/878126
        if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP)
            return false;
        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        final int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName());
        boolean granted = false;
        if (mode == AppOpsManager.MODE_DEFAULT)
            granted = (context.checkCallingOrSelfPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) == PackageManager.PERMISSION_GRANTED);
        else
            granted = (mode == AppOpsManager.MODE_ALLOWED);
        return granted;
    }
}

清单文件应具有以下内容:

<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions"/>

标签:android-8-0-oreo,android,storage
来源: https://codeday.me/bug/20191013/1905744.html