Android Studio改写getLastTimeUsed为getTotalTimeInForeground遇时间异常求助
搞定Android UsageStats显示1/1/70的问题
老兄,你踩的这个坑其实挺典型的——为啥换成getTotalTimeInForeground()就输出1/1/70?核心原因是你把「时长」当成「时间戳」来格式化了!
先理清楚两个方法的本质区别:
getLastTimeUsed()返回的是应用最后一次被使用的具体时间点(毫秒级时间戳),比如昨天下午3点打开过它,返回的就是那个时刻的毫秒数,所以用日期格式化没问题。- 但
getTotalTimeInForeground()返回的是应用在统计区间内前台运行的总时长(毫秒),比如这个应用今天前台跑了1小时20分,返回的就是对应毫秒数,你拿它去转日期,自然会把0或者小数值转成epoch起始点(也就是1970年1月1日)。
接下来一步步解决:
1. 先把显示逻辑改成处理「时长」
把原来用来格式化时间戳的代码,换成时长格式化的逻辑。比如原来的代码可能是这样的:
// 原来处理getLastTimeUsed的错误写法 long time = usageStats.getLastTimeUsed(); tvUsageTime.setText(new SimpleDateFormat("MM/dd/yy").format(new Date(time)));
现在改成处理时长的代码:
// 正确处理getTotalTimeInForeground的写法 long totalForegroundMs = usageStats.getTotalTimeInForeground(); // 把毫秒转成人类可读的时长格式 String duration = formatDuration(totalForegroundMs); tvUsageTime.setText(duration);
然后实现这个formatDuration工具方法,比如:
private String formatDuration(long milliseconds) { long seconds = milliseconds / 1000; long minutes = seconds / 60; long hours = minutes / 60; long days = hours / 24; if (days > 0) { return String.format("%d天 %d小时 %d分钟", days, hours % 24, minutes % 60); } else if (hours > 0) { return String.format("%d小时 %d分钟 %d秒", hours, minutes % 60, seconds % 60); } else if (minutes > 0) { return String.format("%d分钟 %d秒", minutes, seconds % 60); } else { return String.format("%d秒", seconds); } }
2. 检查UsageStats的查询参数是否正确
如果改完显示逻辑后还是拿到0值,那得看看你查询UsageStats的代码有没有问题:
- 确保查询的时间范围覆盖了你想统计的时间段,比如要查最近7天的数据:
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 7 * 24 * 60 * 60 * 1000; // 最近7天的起始时间 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
- 这里用
INTERVAL_BEST比较稳妥,它会根据你设置的时间范围自动选择最合适的统计区间,避免因为区间类型不匹配导致数据拿不到。
3. 最后确认权限和版本适配
- 别忘在Manifest里声明权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
- 这个权限没法通过常规的运行时权限申请,必须引导用户到系统设置的「应用使用权限」页面开启授权,不然拿不到任何数据。
- 另外,
getTotalTimeInForeground()是API 21(Android 5.0)才加的方法,如果你要支持更低版本,记得加版本判断:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { long totalForegroundMs = usageStats.getTotalTimeInForeground(); // 处理时长显示 } else { // 低版本的兼容逻辑,比如提示用户版本过低 }
基本上改完显示逻辑就能解决1/1/70的问题了,如果还是拿不到正确数值,再去排查查询区间和权限的问题。
内容的提问来源于stack exchange,提问作者Miro1771
相关产品推荐
相关产品推荐

