如何在Android O上使用StorageStatsManager.queryStatsForPackage? [英] How to use StorageStatsManager.queryStatsForPackage on Android O?

查看:655
本文介绍了如何在Android O上使用StorageStatsManager.queryStatsForPackage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用Android O之前,要获取应用大小,您必须具有特殊的权限并使用隐藏的API.

Before Android O, in order to get an app size, you had to have a special permission for it, and use a hidden API.

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

Such a solution won't work anymore, but instead, Google provides an official API that's less granular: queryStatsForPackage , which returns StorageStats object.

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

However, I can't find any information of how to use it.

与仅需要应用程序包名称的隐藏API相对,此隐藏API还需要"String volumeUuid"和"UserHandle user".

As opposed to the hidden API, which only required the package name of the app, this one also requires "String volumeUuid" and "UserHandle user".

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

推荐答案

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

OK, I've found out how to use the new API. I've prepared a small sample of this, fetching some information about the volume storage and of a specific app (this time of the Play Store, but you can change it if needed) :

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 = android.os.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) {
        //http://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;
    }
}

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

manifest file should have this:

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

这篇关于如何在Android O上使用StorageStatsManager.queryStatsForPackage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆