Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

queryUsageStats interval duration

I'm using UsageStatsManager API to get usage statistics for a certain time interval. All works fine if I use the predefined intervals i.e. INTERVAL_DAILY, INTERVAL_WEEKLY, INTERVAL_MONTHLY, INTERVAL_YEARLY. But if I want to view the data for the past 2 or 3 hours, I am getting today's data for the whole day. I have tried using Calendars and System.currentTimeMillis() but that didn't give me filtered results.

Calendar approach :

Calendar startCalendar = Calendar.getInstance();
startCalendar.add(Calendar.HOUR_OF_DAY, -2);

Calendar endCalendar = Calendar.getInstance();

And pass this to queryUsageStats method like this:

usageList = usm.queryUsageStats(interval, startCalendar.getTimeInMillis(), endCalendar.getTimeInMillis());

where interval is INTERVAL_BEST.

System.currentTimeMillis() approach :

long startTime = System.currentTimeMillis() - 7200*1000 // 7200 seconds i.e. 2 hrs

long endTime = System.currentTimeMillis();

Pass this to queryUsageStats just like above :

usageList = usm.queryUsageStats(interval, startTime, endTime);

where interval is again INTERVAL_BEST.

I'd like to know whether it's possible to get data for this duration i.e. less than a day, as the INTERVAL_BEST hasn't been documented properly to include this information. Any help would be appreciated as I'm stuck on this problem.

like image 419
gaurav jain Avatar asked Jun 16 '15 07:06

gaurav jain


2 Answers

As UsageStatsManager doc says:

A request for data in the middle of a time interval will include that interval.

It seems that usage data is stored in buckets, and minimum bucket is a day, so you can't query usage stats for period less than a day. Even if you query a one-hour interval for a particular day, usage stats for the whole day is returned.

like image 179
Max77 Avatar answered Feb 08 '23 11:02

Max77


A little late to the party, but I think this might be useful to some.

You could use the queryEvents(long startTime, long endTime) from UsageStatsManager for achieving the desired result. The method could look like this (inspired by this post):

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public HashMap<String, AppUsageInfo> queryUsageStatistics(Context context, long startTime, long endTime) {
    UsageEvents.Event currentEvent;
    List<UsageEvents.Event> allEvents = new ArrayList<>();
    HashMap<String, AppUsageInfo> map = new HashMap<>();
    UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
    assert mUsageStatsManager != null;
    // Here we query the events from startTime till endTime.
    UsageEvents usageEvents = mUsageStatsManager.queryEvents(startTime, endTime);

    // go over all events.
    while (usageEvents.hasNextEvent()) {
        currentEvent = new UsageEvents.Event();
        usageEvents.getNextEvent(currentEvent);
        String packageName = currentEvent.getPackageName();
        if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED || currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED ||
                    currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_STOPPED) {
            allEvents.add(currentEvent); // an extra event is found, add to all events list.
            // taking it into a collection to access by package name
            if (!map.containsKey(packageName)) {
                map.put(packageName, new AppUsageInfo());
            }
        }
    }

    // iterate through all events.
    for (int i = 0; i < allEvents.size() - 1; i++) {
        UsageEvents.Event event0 = allEvents.get(i);
        UsageEvents.Event event1 = allEvents.get(i + 1);

        //for launchCount of apps in time range
        if (!event0.getPackageName().equals(event1.getPackageName()) && event1.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
            // if true, E1 (launch event of an app) app launched
            Objects.requireNonNull(map.get(event1.getPackageName())).launchCount++;
        }

        //for UsageTime of apps in time range
        if (event0.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED &&
                (event1.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED || event1.getEventType() == UsageEvents.Event.ACTIVITY_STOPPED)
                && event0.getPackageName().equals(event1.getPackageName())) {
            long diff = event1.getTimeStamp() - event0.getTimeStamp();
            Objects.requireNonNull(map.get(event0.getPackageName())).timeInForeground += diff;
        }
    }
    // and return the map.
    return map;
}

The AppUsageInfo class would be:

public class AppUsageInfo {

    public long timeInForeground;
    public int launchCount;

    AppUsageInfo() {
        this.timeInForeground = 0;
        this.launchCount = 0;
    }
}

To then get the usage stats for the last two hours, simply call

Calendar startCalendar = Calendar.getInstance();
startCalendar.add(Calendar.HOUR_OF_DAY, -2);
Calendar endCalendar = Calendar.getInstance();

HashMap<String, AppUsageInfo> result = queryUsageStatistics(context, startCalendar.getTimeInMillis(), endCalendar.getTimeInMillis();
like image 38
Jorn Rigter Avatar answered Feb 08 '23 10:02

Jorn Rigter