【问题标题】:How to count app usage time while app is on foreground?应用程序在前台时如何计算应用程序使用时间?
【发布时间】:2020-05-08 10:54:16
【问题描述】:

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

我使用UsageStatsManager 类的queryEvents 方法来计算应用使用时间。

这是我计算应用使用时间的代码(我关注了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) 的时间差)。然后它将这个差异添加到应用程序的总使用时间中。

问题是除非应用程序进入后台,否则无法计算在前台花费的时间。因此,如果超出使用限制,则在应用进入后台之前不会出现通知

应用在前台时是否真的可以获取前台时间?

注意我已经尝试过 queryUsageStatsUsageStats.getTotalTimeInForeground() 但由于 queryUsageStats 有一些与此问题无关的其他问题而无法成功。

【问题讨论】:

    标签: android usagestatsmanager


    【解决方案1】:

    我已经解决了这个问题。

    添加当前运行的应用程序进入前台的当前时间和时间戳的差异就可以了。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      相关资源
      最近更新 更多