androidusage-statistics

Check if my application has usage access enabled


I'm using the new UsageStatsManager API to get current foreground application in Android 5.0 Lollipop. In order to use this API, the user must enable the application in the Settings->Security->Apps with usage access screen.

I send the user directly to this screen with this Intent:


startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));

Now, I want to validate the user enabled my application. I wanted to do so like I validate the user enabled my application to use the NotificationListenerService but I have no idea what is the String key, if it even exists.


Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
// Tried Settings.ACTION_USAGE_ACCESS_SETTINGS as key but it returns null

Second approach was to query the usage stats and check if it returns results (it returns an empty array when the app is not enabled) and it works most of the times but sometimes it returns 0 results even when my app is enabled.


UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService("usagestats");
long time = System.currentTimeMillis();
List stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time);

if (stats == null || stats.isEmpty()) {
    // Usage access is not enabled
}

Is there a way to check if my application has usage access enabled?


Solution

  • Received a great answer by someone on Twitter, tested working:

    try {
       PackageManager packageManager = context.getPackageManager();
       ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
       AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
       int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
       return (mode == AppOpsManager.MODE_ALLOWED);
    
    } catch (PackageManager.NameNotFoundException e) {
       return false;
    }