我正在开发一个安卓应用,用于跟踪每日应用使用情况。我的想法是,用户可以为任何应用设置每日使用时间限制,超过限制后最多2分钟内会出现通知。(延迟的原因。我已经创建了一个报警系统,使用 报警器 类,每分钟都会响起,以运行一个。JobIntentService 它将检查是否超过任何应用程序的限制)
我用过 查询事件 方式 UsageStatsManager 类来计算应用的使用时间。
这是我计算应用使用时间的代码(我按照了 如何使用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。). 然后它把这个差额加到应用的总使用时间上。
问题是,除非应用进入后台,否则无法计算前台的使用时间。所以,如果超过了使用限制,通知不会出现,直到应用程序进入后台。.
其实是否可以在应用处于前景时获取前景时间?
N.B.我已经尝试过 查询使用统计 与...一起 UsageStats.getTotalTimeInForeground() 但无法成功,因为queryUsageStats有一些其他问题,与这个问题无关。
我已经解决了这个问题。
添加当前时间和当前正在运行的应用程序的时间戳的差值到前台就可以了。
我只是在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);
}
这很简单,我应该在发问题之前想清楚的