当应用程序处于前台状态时,如何计算应用程序使用时间? [英] How to count app usage time while app is on foreground?

查看:350
本文介绍了当应用程序处于前台状态时,如何计算应用程序使用时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用,用于跟踪每日的应用使用情况.这个想法是,用户可以为任何应用设置每日时间限制,超过该限制后最多2分钟内会出现一条通知. (延迟的原因:我使用 AlarmManager 类创建了一个警报系统,该系统每分钟运行一次 JobIntentService ,该系统将检查是否超出了任何应用程序的限制)

I'm working on an android app for tracking daily app usage. The idea is that a user can set daily time limit for any app and a notification will appear within at most 2 minutes after the limit is exceeded. (The reason for delay: I've created an alarm system using AlarmManager class that will go off every minute to run a JobIntentService which will check whether limit for any app is exceeded)

我使用了 queryEvents UsageStatsManager 类的a>方法来计算应用使用时间.

I've used queryEvents method of UsageStatsManager class to count app usage time.

这是我用来计算应用使用时间的代码(我遵循了如何使用queryEvents ):

Here's my code for counting app usage time (I've followed How to use queryEvents):

HashMap<String, Integer> getTimeSpent(Context context, String packageName, long beginTime, long endTime) {
    UsageEvents.Event currentEvent;
    List<UsageEvents.Event> allEvents = new ArrayList<>();
    HashMap<String, Integer> appUsageMap = new HashMap<>();

    UsageStatsManager usageStatsManager = (UsageStatsManager)context.getSystemService(Context.USAGE_STATS_SERVICE);
    UsageEvents usageEvents = usageStatsManager.queryEvents(beginTime, endTime);

    while (usageEvents.hasNextEvent()) {
        currentEvent = new UsageEvents.Event();
        usageEvents.getNextEvent(currentEvent);
        if(currentEvent.getPackageName().equals(packageName) || packageName == null) {
            if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
                    || currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {
                allEvents.add(currentEvent);
                String key = currentEvent.getPackageName();
                if (appUsageMap.get(key) == null)
                    appUsageMap.put(key, 0);
            }
        }
    }

    for (int i = 0; i < allEvents.size() - 1; i++) {
        UsageEvents.Event E0 = allEvents.get(i);
        UsageEvents.Event E1 = allEvents.get(i + 1);

        if (E0.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
                && E1.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED
                && E0.getClassName().equals(E1.getClassName())) {
            int diff = (int)(E1.getTimeStamp() - E0.getTimeStamp());
            diff /= 1000;
            Integer prev = appUsageMap.get(E0.getPackageName());
            if(prev == null) prev = 0;
            appUsageMap.put(E0.getPackageName(), prev + diff);
        }
    }
    return appUsageMap;
}

简而言之,上面的代码计算了应用进入前台时的时间戳( UsageEvents.Event.ACTIVITY_RESUMED )和进入后台时的时间戳( UsageEvents.Event.ACTIVITY_PAUSED)的时差).然后,将这种差异添加到应用程序的总使用时间中.

In short the above code counts the time difference of the timestamp when an app goes foreground (UsageEvents.Event.ACTIVITY_RESUMED) and the timestamp when it goes background (UsageEvents.Event.ACTIVITY_PAUSED). Then it adds this difference to the total usage time of the app.

问题在于,除非应用程序变为后台,否则无法计算花费在前台的时间.因此,如果超出了使用限制,则直到应用程序变为后台状态,通知才会出现.

在应用程序处于前台状态时,实际上是否可以获得前台时间?

Is it actually possible to get foreground time while app is on foreground?

N.B.我已经尝试过 queryUsageStats 以及 UsageStats.getTotalTimeInForeground()但无法成功,因为queryUsageStats还有其他与此问题无关的问题.

N.B. I've tried queryUsageStats along with UsageStats.getTotalTimeInForeground() but couldn't succeed since queryUsageStats had some other issues not related to this question.

推荐答案

我已经解决了这个问题.

I've solved the issue.

添加当前时间和当前正在运行的应用程序进入前台的时间戳之间的差异就可以解决问题.

Adding difference of current time and timestamp of current running app going foreground does the trick.

我刚刚在return语句之前添加了以下代码:

I just added the following code before the return statement:

UsageEvents.Event lastEvent = allEvents.get(allEvents.size() - 1);
if(lastEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
    int diff = (int)System.currentTimeMillis() - (int)lastEvent.getTimeStamp();
    diff /= 1000;
    Integer prev = appUsageMap.get(lastEvent.getPackageName());
    if(prev == null) prev = 0;
    appUsageMap.put(lastEvent.getPackageName(), prev + diff);
}

这很简单,在发布问题之前我应该​​考虑一下.

It is pretty straightforward, I should have thought about it before posting the question.

这篇关于当应用程序处于前台状态时,如何计算应用程序使用时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆