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?
There is actually an example app included in AOSP sample code:
developers/samples/android/system/AppUsageStatistics/
It includes all the bits necessary to use
UsageStats
in an app:Declaring the permission in
AndroidManifest.xml
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
Show settings to grant permission to access
UsageStatsManager
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
Query
UsageStatsManager
for statistics.Creating a list of apps based on
UsageStats
To summarize and apply to your example:
UsageStats
system service.beginTime
andendTime
are measured in milliseconds since the epoch.Calendar
instances can give you this value withgetTimeinMillis()
. What you erroneously do is to only give the year numbers (2015
and2017
if you would run the program today). These values are interpreted as milliseconds since the epoch and thus the interval is only 2 milliseconds long and is some time in 1970.Instead of the following code snippet that you posted, you should copy the example I posted below:
Wrong:
Correct:
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.
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).
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.
-Credit MRK; corrected by me (he accidentally just put cal instead of beginCal and endCal)
The code for the usage access settings is below. :)
If you want to see usage statistics of a specific time period. You have to first calculate the length of time in milliseconds of the start and end of your time period, since the epoch. (epoch is the number of seconds that have elapsed since 00:00:00 UTC, Thursday 1, 1970.) Or, as I will show in the following sample code, an easy way is to calculate backwards from the current time in milliseconds.
For example, if you want stat of the past 4 days, it would be:
The number 345600000 is the amount of milliseconds of 4 days.
And for the INTERVAL_TYPE this explains it well.
you can do like this