androidusage-statisticsactivity-managerandroid-recentsusagestatsmanager

How to use UsageStatsManager?


Background

Google has deprecated the function "getRecentTasks" of "ActivityManager" class. Now all it does is to get the list of apps that the current app has opened.

I've even written a post about it here on StackOverflow, but I noticed it's impossible.

The problem

I've made a post about it (here, and another, similar one created by someone else, here) and requested to re-consider it, and Google decided to make a new class, that seem to provide a similar functionality (more like statistics, but might also be useful), but I can't find out how to use it.

The class is called "UsageStatsManager", and my guess is that the function "queryUsageStats" does the job.

Also, it seems it has a new permission ("android.permission.PACKAGE_USAGE_STATS"), which is a system permission, but it's written that:

declaring the permission implies intention to use the API and the user of the device can grant permission through the Settings application.

Here's another link about this new functionality.

What I've found

I've looked at the code of Android, and noticed that "Context" has USAGE_STATS_SERVICE , which in the JavaDocs say the next thing:

/**
 * Use with {@link #getSystemService} to retrieve a {@link
 * android.app.UsageStatsManager} for interacting with the status bar.
 *
 * @see #getSystemService
 * @see android.app.UsageStatsManager
 * @hide
 */
public static final String USAGE_STATS_SERVICE = "usagestats";

The weird thing is that not only it says "status bar", but also the packageName doesn't match (should be "android.app.usage.UsageStatsManager" instead) .

I've also added the correct permission:

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

and here's the code I use:

  final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE);
  final int currentYear=Calendar.getInstance().get(Calendar.YEAR);
  final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);

In the emulator itself, I went to "Settings"->"security"->"apps with usage access" , and enabled my app.

However, when running the code, all I get is an empty list...

The question

How do you use UsageStatsManager ?

Also, how do you let the user to grant the permission in the easiest way possible? Or is it automatically done, as soon as the app tries to get the needed information?

What happens when trying to use this class yet the user hasn't confirmed it yet?

How can I make the code return me a real list of apps?


Solution

  • I think the documentation was just short hand for the Calendar stuff. I don't think it actually works with just 2014; however I can be wrong.

    In order to access the actually list of UsageStats, you would need to create a Calendar object with the correct month,day, and year. Exactly how MRK said in the other answer. I copied and corrected the errors in MRK's code so anyone who sees it in the future can see it.

    Calendar beginCal = Calendar.getInstance();
    beginCal.set(Calendar.DATE, 1);
    beginCal.set(Calendar.MONTH, 0);
    beginCal.set(Calendar.YEAR, 2012);
    
    Calendar endCal = Calendar.getInstance();
    endCal.set(Calendar.DATE, 1);
    endCal.set(Calendar.MONTH, 0);
    endCal.set(Calendar.YEAR, 2014);
    
    final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis());
    

    -Credit MRK; corrected by me (he accidentally just put cal instead of beginCal and endCal)

    The code for the usage access settings is below. :)

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