问题描述:

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?

网友答案:

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);
网友答案:

I've created a sample of how to use UsageStats on my Github. Hopefully it can be of help to someone

https://github.com/ColeMurray/UsageStatsSample

网友答案:

Answering your last question "How can I make the code return me a real list of apps?". queryUsageStats takes begin time and end time in milliseconds, not the value of the year in int.

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());

This should return a list of UsageStats for the years 2012 and 2013 (keep in mind the end time is exclusive of the end result time range).

网友答案:

Use UsageStats will get the wrong information when user opens the notification drawer or on a locked screen. You have to use UsageStatsManager.queryEvents() and look for the latest event with MOVE_TO_FOREGROUND event type.

网友答案:

you can do like this

//noinspection ResourceType
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);
相关阅读:
Top