zoukankan      html  css  js  c++  java
  • Android 时间 更新与同步

    欠账太多,做了好多年的驱动,做得多记录的少,一直想找机会,把驱动部分的内容整理下,形成文字;现在倒好,工作内容网framework走了,本打算做一点记录一点,可是现在回想一下,整个camera framework自己改动了一遍,花了好些时间,确没留下点莫子记录;突然又跑到wifi、wpa这边解决问题来了,刚解决完,还有好些没弄明白的地方,正想研究一下,写个文档;这倒好又切到用gps 时间来更新系统时间这个需求上面来了,这个比较简单些,就写了点东西,分享与记录一下;要不马上被催着去调ril了,又没心情写了。

    一、概述

    Android的时间更新分成2种,一种是走运营商协议的NITZ,另一种是走网络时钟的SNTP;

    个人认为如果有GPS的话,可以使用GPS的时钟信息对系统时间进行更新,当然这部分内容可能需要自己去实现,先初略的看了一下,大概需要用到一下一些方法:

    SystemClock.setCurrentTimeMillis(time); // 设置系统时间

    Android.location.location.getTime();//获取Gps时间,可能会有一两分钟的延时,在收到星以后。

    二、问题

    目前所用fsl imx51 Android2.3系统时间无法更新,用的是华为的cdma模块。需要查明并修正,已经看是否能够将第三种系统时间更新方法加入其中。

    三、分析

    基于Android2.3做以下分析

    • 当选择设置菜单----->日期和时间------->自动,系统如下处理
    1. UI显示 :见DateTimeSetting.java         

     public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {

            …………..

            } else if (key.equals(KEY_AUTO_TIME)) {

                boolean autoEnabled = preferences.getBoolean(key, true);

                Settings.System.putInt(getContentResolver(),

                        Settings.System.AUTO_TIME,

                        autoEnabled ? 1 : 0);

                mTimePref.setEnabled(!autoEnabled);

                mDatePref.setEnabled(!autoEnabled);

                mTimeZone.setEnabled(!autoEnabled);

            }

        }

    注释:这是一个监听,当点击自动checkbox后,会触发此监听事件,其中设置了Settings.System.AUTO_TIME的值,disable/enable了时间、日期、区域三个选择项

    1. 后台处理:见CdmaServiceStateTracker.java

     cr.registerContentObserver(   //M.jr.xu when System.AUTO_TIME changed,then callback mAutoTimeOberver

                    Settings.System.getUriFor(Settings.System.AUTO_TIME), true,

                    mAutoTimeObserver);

            setSignalStrengthDefaultValues();

    注释:设置Settings.System.AUTO_TIME的监听

    private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {

            @Override

            public void onChange(boolean selfChange) {

                Log.i("CdmaServiceStateTracker", "Auto time state called ...");

                revertToNitz();

            }

    注释:Settings.System.AUTO_TIME的监听处理函数

     private void revertToNitz() {

            if (Settings.System.getInt(cr, Settings.System.AUTO_TIME, 0) == 0) {

                return;

            }

            Log.d(LOG_TAG, "Reverting to NITZ: tz='" + mSavedTimeZone

                    + "' mSavedTime=" + mSavedTime

                    + " mSavedAtTime=" + mSavedAtTime);

            if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) {

                setAndBroadcastNetworkSetTimeZone(mSavedTimeZone);

                setAndBroadcastNetworkSetTime(mSavedTime

                        + (SystemClock.elapsedRealtime() - mSavedAtTime));

            }

        }

    注释:Settings.System.AUTO_TIME真正的处理函数,其取得从gsm/cdma取得的时间参数,对系统时间已经区域进行更新,并发送广播消息。

                 如果想用到SNTP网络时间同步的话,可以再此函数里面增加相应的代码,这方面网络资料很多,详见http://blog.sina.com.cn/s/blog_3e4774e30100tq2p.html

    • 系统又是如何自动进行时间同步的呢,当选择自动设置以后

            系统时间同步,是靠ril层(见Reference-ril.c)发消息RIL_UNSOL_NITZ_TIME_RECEIVED来进行驱动的,这里就不详细介绍此消息是如何发生的了,其主要由gsm/cdma模块来进行驱动的,想更深入的了了解,需要对RIL、MUX、AT、运营商协议 以及代码进行综合的分析,在这里就不做详细介绍,如果以后有机会再次深入的介入这一部分内容,将会另外做详细的分析。

            1)当Ril.java 接收到RIL_UNSOL_NITZ_TIME_RECEIVED消息,会将消息转发为EVENT_NITZ_TIME,同时在CdmaServiceStateTracker中handleMessage会接收到EVENT_NITZ_TIME消息了,并进行相关处理,详细代码见下:

              public void handleMessage (Message msg) {

              ……..

             

             case EVENT_NITZ_TIME:

                ar = (AsyncResult) msg.obj;

     

                String nitzString = (String)((Object[])ar.result)[0];

                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();

     

                setTimeFromNITZString(nitzString, nitzReceiveTime);

                break;

               }

            注释:EVENT_NITZ_TIME消息处理,获取gsm/cdma发送过来的时间参数,并且调用setTimeFromNITZString进行处理

      private

        void setTimeFromNITZString (String nitz, long nitzReceiveTime)

        {

                         ……   

                    if (getAutoTime()) {  //M.jr.xu for auto up sys time

                        /**

                         * Update system time automatically

                         */

                        long gained = c.getTimeInMillis() - System.currentTimeMillis();

                        long timeSinceLastUpdate = SystemClock.elapsedRealtime() - mSavedAtTime;

                        int nitzUpdateSpacing = Settings.Secure.getInt(cr,

                                Settings.Secure.NITZ_UPDATE_SPACING, mNitzUpdateSpacing);

                        int nitzUpdateDiff = Settings.Secure.getInt(cr,

                                Settings.Secure.NITZ_UPDATE_DIFF, mNitzUpdateDiff);

     

                        if ((mSavedAtTime == 0) || (timeSinceLastUpdate > nitzUpdateSpacing)

                                || (Math.abs(gained) > nitzUpdateDiff)) {

                            Log.i(LOG_TAG, "NITZ: Auto updating time of day to " + c.getTime()

                                    + " NITZ receive delay=" + millisSinceNitzReceived

                                    + "ms gained=" + gained + "ms from " + nitz);

     

                            setAndBroadcastNetworkSetTime(c.getTimeInMillis());

                        } else {

                            Log.i(LOG_TAG, "NITZ: ignore, a previous update was "

                                    + timeSinceLastUpdate + "ms ago and gained=" + gained + "ms");

                            return;

                        }

                    }

                 注释:setTimeFromNITZString时间更新处理函数,当自动选择框为true,当获取的时间值和系统的时间值大于一定时,调用setAndBroadcastNetworkSetTime(c.getTimeInMillis())对系统时间进行更新,并且发送广播消息TelephonyIntents.ACTION_NETWORK_SET_TIME,在2.3当中此广播消息不会被接收到,也就是说没有说明作用,但是在4.0版本里面,此广播消息被NetWorkTimeupdataService接收到,并且进行了相关的时间同步处理(网络时钟SNTP),这一部分在这里就不做介绍了,原理和NITZ更新时间差不多,感兴趣的自己去研究一下。

    四、总结

         Android系统时间同步,从代码上分析不是很复杂,但是目前Android2.3的同步只用到的Gsm/Cdma NITZ的同步机制,而未加入SNTP同步机制,更别说gsp时间同步机制了,依照其实现原理,实现他们应该都不是很难。

  • 相关阅读:
    JavaScript中创建对象的几种模式
    Vue学习5:条件渲染
    Vue学习4:class与style绑定
    Vue学习3:计算属性computed与监听器
    Vue学习2:模板语法
    普通递归与优化递归
    new操作符具体干了什么呢?
    各种形式存放token
    用es6的Array.reduce()方法计算一个字符串中每个字符出现的次数
    ES6 对象的解构赋值
  • 原文地址:https://www.cnblogs.com/AdiSky/p/2795168.html
Copyright © 2011-2022 走看看