Android设备开机时间统计

来源:互联网 发布:ubuntu镜像下载地址 编辑:程序博客网 时间:2024/05/29 07:39
现在有一个需求:Android设备在开机的时候统计开机时间,然后上报至服务器。
一般来说我们都是这样做的:在收到开机广播后,调用System.currentTimeMillis()获取开机时的时间戳,然后将其上报至服务器。可是有一个问题不知道你有没有想过,如果此时这个Android设备的系统时间与标准北京时间相比不准确呢?假如现在北京时间是2016年12月2日 17:00:00,那么转换为时间戳是1480669200000(单位:毫秒),而此Android设备的系统时间为2016年1月1日 8:00:00,那么获取的时间戳为1451606400000(单位:毫秒),你可不能把这个时间戳给上报至后台服务器吧?要想解决这个问题,得先知道下面这个方法。
  • elapsedRealtime
此方法为Android特有的类SystemClock里面的一个方法,先看一下官方文档给的解释:
  1. /**
  2. * Returns milliseconds since boot, including time spent in sleep.
  3. *
  4. * @return elapsed milliseconds since boot.
  5. */
  6. native public static long elapsedRealtime();
此方法可以获取Android设备的开机时长,包括睡眠时间,也就是说调用此方法可以获取设备开机时到调用此方法时的完整时间。此方法是与时间戳无关的,不管系统在这个时间段是否更新校验时间。
那么我们知道了这个方法后,应该怎么用起来呢?其实很简单,当设备开机后,将开机时间戳startTime记录下来,然后从网络获取标准的北京时间的时间戳standardTime,用此时间戳standardTime减去该设备的开机时长elapsedRealtime(),那么此时得到一个新的时间戳就是开机时的时间戳newStartTime,再用此时间戳newStartTime和之前记录的开机时间戳startTime比较,如果误差大于1分钟(一般来说设备通电开机到发送开机广播是有几十秒的,该时间会被统计到开机时长中),那么就将新的开机时间戳newStartTime上报至服务器,这样可以解决文章开头提到的问题,除非设备一直不联网,那这样谁也没办法啦~具体代码如下:
    1.在开机广播中获取开机时间戳
  1. // 一般将此时间戳保存下来以便后面校验,推荐用SharedPreferences保存
  2. // 文章末尾贴出了SharedPreferences的工具类,有需要的可以看看
  3. long startTime = System.currentTimeMillis();
  4. SharePreferenceUtils.newInstance(context).setLong("startTime", startTime);
    2.从网络获取标准北京时间的时间戳
  1. // 获取网络时间
  2. public static long getNetTime() {
  3. long standardTime;
  4. try {
  5.        //取得资源对象,网址可替换
  6. URL url = new URL("http://www.baidu.com");
  7.        //生成连接对象
  8. URLConnection uc = url.openConnection();
  9.        //发出连接
  10. uc.connect();
  11.        //取得网站日期时间
  12. standardTime = uc.getDate();
  13. return standardTime;
  14. } catch (Exception e) {
  15. e.printStackTrace();
  16. }
  17. return 0;
  18. }
    3.校验开机时间戳
  1. // 校验开机时间戳
  2. public static void checkBootTime() {
  3. // 获取开机时长
  4. long runTime = SystemClock.elapsedRealtime();
  5. // 获取开机时间戳
  6. long bootTime = SharePreferenceUtils.newInstance(context).getLong("startTime", 0);
  7. // 获取新的开机时间戳
  8. long newBootTime = getNetTime() - runTime;
  9. if (newBootTime - bootTime > 1 * 60 * 1000) {
  10. bootTime = newBootTime;
  11. }
  12. // 此处可以上报校验后的开机时间戳bootTime
  13. ...
  14. }
以上就是更新校验开机的时间戳全部思路过程和代码,下面贴上SharedPreferences的工具类代码:
  1. public class SharePreferenceUtils {
  2. private static SharedPreferences sp;
  3. private static SharePreferenceUtils utils;
  4. private static String spName = "mysp";
  5. public static SharePreferenceUtils newInstance(Context context) {
  6. if (sp == null) {
  7. synchronized (SharePreferenceUtils.class) {
  8. if (sp == null) {
  9. sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
  10. }
  11. }
  12. }
  13. if (utils == null) {
  14. synchronized (SharePreferenceUtils.class) {
  15. if (utils == null) {
  16. utils = new SharePreferenceUtils();
  17. }
  18. }
  19. }
  20. return utils;
  21. }
  22. public static SharePreferenceUtils newInstance(Context context,String spName) {
  23. if (sp == null) {
  24. synchronized (SharePreferenceUtils.class) {
  25. if (sp == null) {
  26. sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
  27. }
  28. }
  29. }
  30. if (utils == null) {
  31. synchronized (SharePreferenceUtils.class) {
  32. if (utils == null) {
  33. utils = new SharePreferenceUtils();
  34. }
  35. }
  36. }
  37. return utils;
  38. }
  39. /**
  40. * 保存String值
  41. *
  42. * @param key
  43. * @param value
  44. */
  45. public void setString(String key, String value) {
  46. sp.edit().putString(key, value).commit();
  47. }
  48. /**
  49. * 获取String值
  50. *
  51. * @param key
  52. * @param defValue
  53. * @return
  54. */
  55. public String getString(String key, String defValue) {
  56. return sp.getString(key, defValue);
  57. }
  58. /**
  59. * 保存int值
  60. *
  61. * @param key
  62. * @param value
  63. */
  64. public void setInt(String key, int value) {
  65. sp.edit().putInt(key, value).apply();
  66. }
  67. /**
  68. * 获取int值
  69. *
  70. * @param key
  71. * @param defValue
  72. * @return
  73. */
  74. public int getInt(String key, int defValue) {
  75. return sp.getInt(key, defValue);
  76. }
  77. /**
  78. * 保存boolean值
  79. *
  80. * @param key
  81. * @param value
  82. */
  83. public void setBoolean(String key, boolean value) {
  84. sp.edit().putBoolean(key, value).commit();
  85. }
  86. /**
  87. * 获取boolean值
  88. *
  89. * @param key
  90. * @param defValue
  91. * @return
  92. */
  93. public boolean getBoolean(String key, boolean defValue) {
  94. return sp.getBoolean(key, defValue);
  95. }
  96. /**
  97. * 保存long值
  98. *
  99. * @param key
  100. * @param value
  101. */
  102. public void setLong(String key, long value) {
  103. sp.edit().putLong(key, value).apply();
  104. }
  105. /**
  106. * 获取long值
  107. *
  108. * @param key
  109. * @param defValue
  110. * @return
  111. */
  112. public long getLong(String key, long defValue) {
  113. return sp.getLong(key, defValue);
  114. }
  115. }




0 0
原创粉丝点击