如何检查是否与QUOT; android.permission.PACKAGE_USAGE_STATS"许可给?android、QUOT、permission、许可

2023-09-13 01:23:53 作者:春心荡漾 ξ

我试图让应用程序推出的统计数据,以及棒棒堂有可能通过使用UsageStatsManager一流的,因为这样(原职 此处 ):

I'm trying to get app-launched statistics, and on Lollipop it's possible by using the UsageStatsManager class, as such (original post here):

清单:

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

打开,可以让用户确认给你这个权限的活动:

opening the activity that will let the user confirm giving you this permission:

startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));

获取统计,汇总:

getting the stats, aggregated :

 private static final String USAGE_STATS_SERVICE ="usagestats"; // Context.USAGE_STATS_SERVICE);
 ...
 final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService(USAGE_STATS_SERVICE);
 final Map<String,UsageStats> queryUsageStats=usageStatsManager.queryAndAggregateUsageStats(fromTime,toTime);

问题

我似乎无法检查,如果你需要(android.permission.PACKAGE_USAGE_STATS)的权限授予。所有我试过到目前为止始终返回时被拒绝。

The problem

I can't seem to check if the permission that you need ("android.permission.PACKAGE_USAGE_STATS") is granted. All I've tried so far always returns that it is denied.

在code工作,但权限检查无法正常工作。

The code works, but the permission check doesn't work well.

您可以检查权限被授予使用任何这样的:

you can check for a permission being granted using either this:

String permission = "android.permission.PACKAGE_USAGE_STATS";
boolean granted=getContext().checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;   

或者这样的:

or this:

String permission = "android.permission.PACKAGE_USAGE_STATS";
boolean granted=getPackageManager().checkPermission(permission,getPackageName())== PackageManager.PERMISSION_GRANTED;   

这两个总是返回它得到了否认(即使我已经授予的权限为用户)。

Both always returned that it got denied (even when I've granted the permission as a user).

看着UsageStatsManager的code,我试着想出这个解决方法:

Looking at the code of UsageStatsManager, I've tried to come up with this workaround:

      UsageStatsManager usm=(UsageStatsManager)getSystemService("usagestats");
      Calendar calendar=Calendar.getInstance();
      long toTime=calendar.getTimeInMillis();
      calendar.add(Calendar.YEAR,-1);
      long fromTime=calendar.getTimeInMillis();
      final List<UsageStats> queryUsageStats=usm.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,fromTime,toTime);
      boolean granted=queryUsageStats!=null&&queryUsageStats!=Collections.EMPTY_LIST;

它的工作,但它仍然是一个解决办法。

It worked, but it's still a workaround.

为什么我没有得到许可检查的正确的结果?

How come I don't get the correct result of the permission check?

应该做哪些检查一下比较好?

What should be done to check it better?

推荐答案

这是授予在系统设置中用户特殊权限(使用情况统计信息的访问,通知接入,...)通过的 AppOpsManager ,其中加入的Andr​​oid 4.4系统。

Special permissions that are granted by the user in the system settings (usage stats access, notification access, …) are handled by AppOpsManager, which was added in Android 4.4.

请注意,除了用户授予你,你通常需要在Android清单(或某个组件)权限在系统设置访问,没有你的应用程序甚至没有在系统设置中显示。对于使用情况统计信息需要 android.permission.PACKAGE_USAGE_STATS 许可。

Note that besides user granting you access in the system settings you typically need a permission in the Android manifest (or some component), without that your app doesn't even show in the system settings. For usage stats you need android.permission.PACKAGE_USAGE_STATS permission.

有不是那么多的文件,但你可以随时检查Android的源吧。 该解决方案似乎有点哈克因为一些常量后来加入 AppOpsManager ,和一些常量(如检查不同的权限)仍然隐藏在私有的API。

There's not much documentation about that but you can always check Android sources for it. The solution might seem bit hacky because some constants were added later to the AppOpsManager, and some constants (e.g. for checking different permissions) are still hidden in private APIs.

AppOpsManager appOps = (AppOpsManager) context
        .getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow("android:get_usage_stats", 
        android.os.Process.myUid(), context.getPackageName());
boolean granted = mode == AppOpsManager.MODE_ALLOWED;

这告诉你,如果权限被授予用户。 请注意,由于空气污染指数21有不断的 AppOpsManager.OPSTR_GET_USAGE_STATS =机器人:get_usage_stats

This tells you if the permission was granted by the user. Note that since API level 21 there is constant AppOpsManager.OPSTR_GET_USAGE_STATS = "android:get_usage_stats".

我测试此检查棒棒糖(包括5.1.1),它工作正常。它告诉我用户是否给了明确的许可,没有任何崩溃。 还有方法 appOps.checkOp()这可能会抛出一个 SecurityException异常

I tested this check on Lollipop (including 5.1.1) and it works as expected. It tells me whether the user gave the explicit permission without any crash. There's also method appOps.checkOp() which might throw a SecurityException.