7

Since Android Lollipop, we have now an API for accessing apps usage stats. However, your app must be granted those permissions by the user.

I know that for redirecting the user to those settings using Settings.ACTION_USAGE_ACCESS_SETTINGS.

Now, my question is how do you know the user has granted you those permissions so that you can stop redirecting him to the settings.

Thanks!

lage
  • 589
  • 2
  • 5
  • 18
  • http://stackoverflow.com/questions/27215013/check-if-my-application-has-usage-access-enabled – Senthil Kumar Jan 28 '15 at 06:35
  • Possible duplicate of [Check if my application has usage access enabled](https://stackoverflow.com/questions/27215013/check-if-my-application-has-usage-access-enabled) – Sam Feb 23 '19 at 03:34

4 Answers4

7

you can simply query usagestats with daily interval and end time the current time and if nothing is returned this means the user hasn’t granted permissions

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean doIHavePermission(){


    final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
    final List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0,  System.currentTimeMillis());

    return !queryUsageStats.isEmpty();
}

Daily interval with start date 0 and end date the current time must at least return todays usage.So it will be empty only if permissions are not granted.

Junyue Cao
  • 421
  • 6
  • 13
tzanou
  • 122
  • 3
  • Thanks for the answer. That's actually what I am already doing, I was hoping for a cleaner way. Especially because these queries are a bit slow. – lage Dec 06 '14 at 18:50
  • Maybe you can limit the time range for example set start date to yesterday in order to return less statistics.But I see your point... – tzanou Dec 06 '14 at 19:18
  • If you put a large time range it will take too long, if you put a short one, it can happen the user has not been using the phone... Anyway, if no one comes up with a better answer in the next days I'll just accept yours. Thanks – lage Dec 09 '14 at 13:48
  • This is also the way we do it. We persist a "was last able to get any usage stat data" timestamp, if this is > 0 then the privilege must exist. It appears Google has not published a way to get at this setting directly yet. If you look in the Android src code it appears there is one there, but it is not reachable in the SDK yet (not a public setting). FYI Also note that we have identified some "Android 5" devices that are entirely missing the app.usage features at all (LG G3 and Samsung S5 so far). – Mark Feb 23 '15 at 19:07
7

Check this answer: Tomik's answer

If you hurry, here's the solution ;)

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static boolean usageAccessGranted(Context context) {
       AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
       int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
       android.os.Process.myUid(), context.getPackageName());
       return mode == AppOpsManager.MODE_ALLOWED;
    }
Community
  • 1
  • 1
2

I stumbled on the same problem. On Samsung S5 Lollipop usage stats did not work with the following code:

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

However usage stats actually exist. With the following code one can open the security settings:

Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.Settings$SecuritySettingsActivity"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

An the scroll to the bottom and there is usage stats. I also inspeced logs and by pressing usage stats, you are directed to SubActivity which contains UsageStats fragment. I tried the following code:

Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.SubSettings"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

But got security exception. The problem is that they didnt mark SubActivity as exported, so as far as I know its not possible to directly start SubActivity (usage stats window). The only solution is to take user to Securiy settings and them tell him to manually go to usage stats view and enable app.

If someone finds better solution it would be great!

klemzy
  • 492
  • 1
  • 6
  • 12
  • I know it's a bit late, but I managed to do it with `Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$UsageAccessSettingsActivity")); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);` – Eduardo Herzer Oct 19 '15 at 20:02
  • This is a good answer, but it's in the wrong question. Can you move it here? https://stackoverflow.com/q/27874224/238753 – Sam Feb 23 '19 at 03:31
  • @EduardoHerzer, I tested your solution on Samsung Galaxy S5 SM-G900I running Android 5.0 G900IZTU1BOA1 firmware, and it didn't work for me. Do you remember which device and firmware you used? And can you confirm that `Settings.ACTION_USAGE_ACCESS_SETTINGS` didn't work? – Sam Feb 25 '19 at 20:25
1

See ActivityNotFoundException in Lollipop when trying to launch activity with intent android.settings.USAGE_ACCESS_SETTINGS for a better way, since with method we cannot discern whether there are simple no stats for the time interval

Community
  • 1
  • 1
user3768443
  • 101
  • 3
  • Can you post the relevant content from your link? – Robert Feb 19 '15 at 15:58
  • This won't tell you if the setting is set to true. This other thread is dealing with the issue that the some Android 5 builds are actually missing the entire app usage library (or at least the intent names). – Mark Feb 23 '15 at 19:10