我正在开发一个Android应用程序并通过确定系统首次启动时间来解决问题。我的意思是我需要测量从设备首次启动已经过了多少时间。
我知道有关侦听ACTION_BOOT_COMPLETED的解决方案并在SharedPreferences中保存任何内容,但我需要另一个解决方案,因为这个解决方案在某些情况下不起作用。也许有任何系统属性?
使用案例(摘自discussion)
System.currentMillis()
解决此问题的银弹将是一个时间戳,它计算自首次启动(出厂重置后)后的秒数。就像SystemClock.elapsedRealtime()
一样,但每次启动后都没有重置。不幸的是,到目前为止的答案告诉我们,这个银弹不存在。
然而,许多答案显示了如何解决这个问题的各种选择。 OneWorld123评论了每个答案,它是如何满足他的需求的。
答案 0 :(得分:13)
也许有任何系统属性?
不确定系统属性,但有SystemClock
类提供API以获得系统正常运行时间:
返回自启动以来的毫秒数,不计算在深度睡眠中花费的时间。
您也可以使用SystemClock.elapsedRealtime()
返回自启动以来的毫秒数,包括睡眠时间。
希望这有帮助。
答案 1 :(得分:8)
如果需要知道第一次启动Android设备时,
最简单的方法是拥有一个应用程序
- 安装在工厂图片中
- 配置为在启动期间运行
- 记录当前日期&第一次运行时
sharedPreference
的时间
随后,任何其他需要确定Android设备首次启动时间的应用都可以在设备的生命周期内查找相应的sharedPreference
。 (或直到设备出厂重置;此时预安装的应用程序会在重新启动后将新日期和时间写入共享首选项。)
但是,如果无法在Android设备上预安装应用程序,那么可能会有以下几种解决方法:
可以在首次启动时查找已知在Android设备上创建的目录/文件的时间戳。
使用标准Android API的简单解决方法是检查已知在首次启动时安装的相应系统软件包的安装时间。
/* This returns the last time a package was installed */
PackageManager pm = context.getPackageManager();
PackageInfo pInfo = pm.getPackageInfo(<app-package-name>, 0);
return pInfo.firstInstallTime;
如果我们可以依赖于在首次启动期间一次性更新的特定包(并且永远不会再次),我们可以按如下方式检查其更新时间:
/* This returns the last time a package was updated */
PackageManager pm = context.getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(<app-package-name>, 0);
String appFile = appInfo.sourceDir;
long installed = new File(appFile).lastModified();
答案 2 :(得分:1)
ANDROID SDK中有3种方法: -
public static long elapsedRealtime ()
在API级别1中添加
返回自启动以来的毫秒数,包括睡眠时间。 返回
自启动以来经过的毫秒数。
public static long elapsedRealtimeNanos ()
在API级别17中添加
自启动后返回纳秒,包括睡眠时间。返回
启动后经过的纳秒数。
对于@oneWorld案例:
您可以使用2种方法: -
1)在写入检查某些数据是否具有高于当前日期的日期时,将先前数据的日期更改为小于当前数据和时间的数据, 所以它会返回正确的最新数据。
2)您可以将时间存储在服务器上并从那里检索时间并进行设置。
答案 3 :(得分:1)
如果我们坚持使用SDK,我就不知道直接提供此信息的方法;但是可能有办法从其他资源中获取这些信息。再说一次,如果我们坚持使用SDK,那就相当可靠了#34;选项是使用Android操作系统在设备生命周期内保存的application usage statistics。那是 - 第一个&#34;使用统计数据的时间戳&#34;永远保存。
但是,这显然没有提供准确的首次启动时间&#34;时间戳,所以这取决于你的情况下是否有一些近似值。一般来说,使用统计数据的问题在于Andriod会将其聚合一段时间 - 因此,旧设备 - 日期不太准确。例如,对于我目前的手机,首次在2014年12月3日启动,汇总使用统计数据首先记录在2014年12月21日(记录 - 截至撰写本文时为2016年2月)。 (我不得不承认,虽然我不知道Android操作系统如何安排聚合,如果它只是安排在每年的12月21日,或者它确实有点接近第一个设备使用 - 我想它很容易与任何其他设备检查。)
以下是一些显示UsageStatsManager用法的示例代码,但它肯定需要进行更多调整才能解决更近期更精确的问题:
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
Calendar year2013 = Calendar.getInstance(); year2013.set(2013, 0, 1);
List<UsageStats> stats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_YEARLY, // or adjust for "younger" devices to get more precision - so, you'll probably need several queries
year2013.getTimeMillis(),
Calendar.getInstance().getTimeInMillis());
// now, first element in stats (if it is present at all) will point to the "earliest" statistics saved *for this interval* (yearly in this case)
// use UsageStats.getFirstTimeStamp() to get first known/saved usage
另请注意,如SDK中所述,UsageStatsManager
需要PACKAGE_USAGE_STATS
系统级权限,因此您需要首先让用户在“设置”中接受它:
Intent settingsIntent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(settingsIntent);
希望它有所帮助!
答案 4 :(得分:1)
根据您对http://chat.stackoverflow.com/rooms/102325/discussion-between-ankitagrawal-and-oneworld的讨论,您需要一个单调计数器来唯一标识数据集。
为此,您可以轻松设置SharedPreference,并在每次需要新标识符时递增此值。当您需要知道哪个是最新文件时,只需比较标识符即可。如果在卸载应用程序后重置此计数器是一个问题,请参阅:In android is there any way to preserve SharedPreferences after an uninstall
可以使用的另一种方法是从外部服务器请求时间戳。
希望它有所帮助; - )