Android:对于某些应用,UsageStats 在 getTotalTimeInForeground() 上返回 0

Android: UsageStats returning 0 on getTotalTimeInForeground() for certain apps

我正在尝试使用服务中的以下代码获取我 phone 上安装的每个应用程序的每日屏幕时间。

UsageStatsManager statsManager = (UsageStatsManager)service.getSystemService(Context.USAGE_STATS_SERVICE);

//todayDate is start of the day and today is current time

dailyUsage = statsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, todayDate.toDate().getTime(), today.toDateTime().getMillis());
for(UsageStats stats: dailyUsage){
  Long totalTime = stats.getTotalTimeInForeground();
  String app = stats.getPackageName();
  Log("TotalTimeUsedToday", app + " " + totalTime);
}

我收到重复的应用程序,有些应用程序显示 0 totalTime,但有时它会显示正确的屏幕时间。

由于 queryUsageStats 的工作方式很奇怪,我决定放弃它并改用 queryEvents。这是对我的用例来说非常有用的完整功能:

private Map<String, Long> testUsageStats(long startTime) {

    long currTime = System.currentTimeMillis();
    UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
    UsageEvents usageEvents = mUsageStatsManager.queryEvents(startTime, currTime);

    Map<String, Long> eventUsage = new HashMap<>();
    Map<String, Long> totalUsage = new HashMap<>();

    String lastApp = "xx";

    while (usageEvents.hasNextEvent()) {
        UsageEvents.Event currentEvent = new UsageEvents.Event();
        usageEvents.getNextEvent(currentEvent);

        String app = currentEvent.getPackageName();
        Long time = currentEvent.getTimeStamp();

        if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
            || currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {

            if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
                eventUsage.put(app, time);
                lastApp = app;
            }
            else {
                if (eventUsage.containsKey(app))
                    if (totalUsage.containsKey(app))
                        totalUsage.put(app, totalUsage.get(app) + (time - eventUsage.get(app)));
                    else
                        totalUsage.put(app, (time - eventUsage.get(app)));
                eventUsage.remove(app);
            }
        }
    }

    if(eventUsage.containsKey(lastApp))
        if (totalUsage.containsKey(lastApp))
            totalUsage.put(lastApp, totalUsage.get(lastApp) + (System.currentTimeMillis() - eventUsage.get(lastApp)));
        else
            totalUsage.put(lastApp, (System.currentTimeMillis() - eventUsage.get(lastApp)));

    for (String key : totalUsage.keySet()) {
        Log("TestTimeUsed", key + " " + totalUsage.get(key));
    }

    return totalUsage;

}

此代码段涵盖了当前 运行 应用的边缘情况。在开始时间之前启动应用程序的边缘情况也可以通过一些调整来处理。