android6.0 系统时间不自动校准的问题

    软件平台:android6.0

    硬件平台:MT6797

 

    最近,发现我们产品中有一定概率的时间是不对的,我感到很诧异,我司的产品怎么可以这莫弱鸡,而且android本身的智能性,区区一个时间怎么可能也不会校准,岂非辱没谷歌高士的名声~~~

    其实,时间校准机制android本身早就有了,不过有赖于系统设置项是否开始时区和时间是否自动校准。印象中那两个设置key为auto_time和auto_timezone分别为自动时间和自动时区校准,而我看我们的产品这些都是放开的,那么,到底是啥情况导致时间不去校准呢?

 

    下边跟了系统中关于时间更新的服务,具体代码见frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java

      从代码的逻辑可以看到,这个service是在SystemServer中注册启动的,在systemready之后还会有systemrun的回调进行深度初始化,在这一步中,我们发现注册了网络事件的监听广播。registerForConnectivityIntents,一切看来都很符合逻辑,有网络事件的监测,这样即便开始系统没有网络,无法校准时间,但是在网络通了之后,时间总会实时校准吧?对于我们的板子,这是很奢侈的想法,实际是,网络通了之后并没有同时触发访问时间服务器去更新时间,而是等了上次校准失败后的24小时。

    我说一下时间校准的基本逻辑:

    通常情况,网络如果ok的情况下,在上述service一加载,就会触发时间同步方法,这个方法会尝试访问我们自己定义的时间服务器列表:

     private static final String[] SERVERLIST =  new String[]{
                                             "hshh.org",
                                              "2.android.pool.ntp.org",
                                              "time-a.nist.gov"
                                              };

这个列表在service文件中声明,当然也可以自己添加,系统校准时间的时候会从第一个开始访问,如果能从服务器获取时间则停止访问下一个,而是设置一个config_ntpPollingInterval,这个设置项的定义一般是86400000秒,也就是24小时,说明正常情况下,时间校准24小时一次,防止偏差,而如果第一个服务器访问失败,那么等60s,继续第二个服务器的访问,以此类推,直到最后一个访问完,也没拿到正确时间,就会强制用ntpserver去设置时间,前提是网络通,而如果网络不通,还是会失败的。

我们的设备遇到的情况是时间校准阶段网络不通,上述的流程均未成功获取系统时间,但是网络通了之后,没有触发访问,原来是注册的intentfilter的问题,系统注册的部分如下:

       intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
       mContext.registerReceiver(mConnectivityReceiver, intentFilter);
问题出在这里,网络事件发生之后,并没有收到CONNECTIVITY_ACTION 相关广播,而是ACTION_NETWORK_STATS_UPDATED。

具体改动如下:

diff --git a/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java b/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java
index 13f7569..1598ad0 100644
--- a/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/frameworks/base/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -77,6 +77,9 @@ public class NetworkTimeUpdateService {
     ///M: deubg logging
     private static final boolean DBG = true;
 
+    private static final String ACTION_NETWORK_STATS_UPDATED =
+            "com.android.server.action.NETWORK_STATS_UPDATED";
+

     private static final int EVENT_AUTO_TIME_CHANGED = 1;
     private static final int EVENT_POLL_NETWORK_TIME = 2;
     private static final int EVENT_NETWORK_CHANGED = 3;
@@ -237,6 +240,7 @@ public class NetworkTimeUpdateService {
     private void registerForConnectivityIntents() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        intentFilter.addAction(ACTION_NETWORK_STATS_UPDATED);
         mContext.registerReceiver(mConnectivityReceiver, intentFilter);
     }
 
@@ -360,7 +364,7 @@ public class NetworkTimeUpdateService {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action) || ACTION_NETWORK_STATS_UPDATED.equals(action)) {
                 // Don't bother checking if we have connectivity, NtpTrustedTime does that for us.
                 mHandler.obtainMessage(EVENT_NETWORK_CHANGED).sendToTarget();
             }

 

 

亲测,网络连通的同时,开始了新一波的时间校准操作,时间同步完成~~~~

 

 

    至此,问题解决。。。

   明晚,世界杯1/8对阵:阿根廷对阵法国,希望梅西能顶住,阿根廷顶住,顺利晋级下一轮!!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Android)