I'm attempting to query UsageStats
from UsageStatsManager
, with the aim of returning all app packages that were used daily and for how long.
The Code:
public static List<UsageStats> getUsageStatsList(Context context){
UsageStatsManager usm = getUsageStatsManager(context);
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_YEAR, -1);
long startTime = calendar.getTimeInMillis();
List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime, endTime);
return usageStatsList;
}
I have an alarm that fires daily just before midnight and query's usagestats and then stores the returned data. At first everything seemed to be working fine and I was getting package results and their active time, however I added a function that would check the results hourly and here is where I made a strange discovery.
The results from UsageStatsManager
seemed to be resetting at different times, instead of at midnight, which is what I would have expected considering I was using INTERVAL_DAILY
as a search parameter.
From the data I saved the package 'time' results seem to be resetting at (Rough timings):
- 3am
- Midday
- 3pm
- Midnight
I realize that there is a correlation between when the package timings reset but is this meant to happen?
I've already seen the following thread and it's where I got a lot of my information from: How to use UsageStatsManager?
Consequently:
Android UsageStatsManager producing wrong output?
In the comments mentions that the data returned from queryUsageStats
can't be trusted and random results are being returned.
Am I missing something simple or is UsageStatsManager
not functioning correctly?
I too noticed this behaviour in API 21,UsageStats data is not maintained for sufficiently long in API 21. it works fine from API 22, If you check in
android /data/system/usagestats
, you will find limited entries in API 21, so its not reliable using it in API 21.For API 21+, You will get the whole day
usagestats
while queryingINTERVAL_DAILY
according toUsageStatsManager
API. If you want to query within hours of day you should usequeryEvents
and iterating them by your own logic.I tried in the following way...
This is the modal class for capturing data for every app:
List<AppUsageInfo> smallInfoList; //global var
here is the method, its easy, go with the flow:
i guess i found what is happening there. First i wrote below code,
(today date is 03.08.2017 00:25:14) and when i sent ("package name",02.08.2017 00.00.00, 03.08.2017 00.00.00); to method, (I sent this dates with calendar, you can search in google, how to set dates like that) I got this input;
then i sent ("package name",03.08.2017 00.00.00, 04.08.2017 00.00.00); to method, I got this input;
And i used app which i sent in method about 1 min. Again i sent method output is:
02:08:2017-03.08.2017
03:08:2017-04.08.2017
As you see they increased both. After i see that i waited untill 03.00 am, I used app about 5 min and i got these outputs.
02:08:2017-03.08.2017
03:08:2017-04.08.2017
To conclude, you should control before day and its last foregroundrunningtime. İf it is same with that days first foreground time. You should eliminate that time and return sum of the others. (Even if i dont know that strange system.) New day's counter starting after 03:00 am.
I hope it will be helpful to you.
I have quiet the same problem and also opened a issue with Google for this. Please have a look at https://issuetracker.google.com/issues/118564471 if this corresponds to what you are describing.
I agree with what is said in that comment you mentioned about
queryUsageStats
not being a trusted source. I've been with playing with theUsageStatsManager
for a little while and it returns inconsistent results based on the time of day. I have found that using theUsageEvent
s and manually calculating the necessary info to be much more trustworthy (at least for daily stats), as they are points in time and don't have any weird calculating errors that would produce different outputs for the same input depending on the time of day.I used @Vishal's proposed solution to come up with my own:
A couple of observations:
Event
s have are in UTC, which is why I convert my start/end query times to UTC from my default time zone, and why I convert the start time back on each event. This one got me for a while...- 1000
and replace with whatever you want.Stat
class and the code to capture whatever info you need. You can keep track of end times, or number of times an app was launched in a day if needed for example.I hope this helps!