本文作者:absurd

来源:http://blog.csdn.net/absurd/article/details/6125588

在 Android的系统设置中,有自动同步网络时间的选项。因为Broncho A1移植到froyo版本之后,我们发现时间同步选项无效了。所以我花了一点时间去研究 Android的网络时间同步的流程。研究的结果让我感到惊讶,Android的网络时间同步居然与SNTP协议无关,甚至与TCP/IP协议也毫无关系。

从设置的应用程序中可以了解到,自动同步网络时间的选项只是修改了Settings.System.AUTO_TIME这个设置:

private void setAutoState(boolean isEnabled, boolean autotimeStatus) {       if (isEnabled == false) {           mAutoPref.setChecked(autotimeStatus);           mAutoPref.setEnabled(isEnabled);       }       else {           Settings.System.putInt(getContentResolver(),              Settings.System.AUTO_TIME, autotimeStatus ? 1 : 0);       }       mTimePref.setEnabled(!autotimeStatus);       mDatePref.setEnabled(!autotimeStatus);       mTimeZone.setEnabled(!autotimeStatus);    }

谁会用这个设置呢?然后从代码中查找Settings.System.AUTO_TIME,主要有下面两处:

telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.javatelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java

GSM和CDMA的实现应该是类似的,这里只是看看GSM: 1. reference-ril/reference-ril.c处理主动上报消息。

    if (strStartsWith(s, "%CTZV:")) {        /* TI specific -- NITZ time */        char *response;        line = p = strdup(s);        at_tok_start(&p);        err = at_tok_nextstr(&p, &response);        free(line);        if (err != 0) {            LOGE("invalid NITZ line %s/n", s);        } else {            RIL_onUnsolicitedResponse (                RIL_UNSOL_NITZ_TIME_RECEIVED,                response, strlen(response));        }}这里是处理模组主动上报的消息,如果是时间和时区消息,则调用RIL_onUnsolicitedResponse。2.RIL_onUnsolicitedResponse会把消息发送给RIL的客户端。
ret = sendResponse(p, client_id);
时间和时区信息的格式在RIL_UNSOL_NITZ_TIME_RECEIVED消息的定义处有说明: "data" is const char * pointing to NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"3.RIL客户端处理RIL_UNSOL_NITZ_TIME_RECEIVED消息(telephony/java/com/android/internal/telephony/RIL.java: processUnsolicited)
            case RIL_UNSOL_NITZ_TIME_RECEIVED:                if (RILJ_LOGD) unsljLogRet(response, ret);                // has bonus long containing milliseconds since boot that the NITZ                // time was received                long nitzReceiveTime = p.readLong();                Object[] result = new Object[2];                result[0] = ret;                result[1] = Long.valueOf(nitzReceiveTime);                if (mNITZTimeRegistrant != null) {                    mNITZTimeRegistrant                        .notifyRegistrant(new AsyncResult (null, result, null));                } else {                    // in case NITZ time registrant isnt registered yet                    mLastNITZTimeInfo = result;                }
是GsmServiceStateTracker向RIL注册的,所以事件会由GsmServiceStateTracker来处理。4.GsmServiceStateTracker 处理EVENT_NITZ_TIME事件:
            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;
这里nitzString是时间字符串,由setTimeFromNITZString负责解析。
private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {            String[] nitzSubs = nitz.split("[/:,+-]");            int year = 2000 + Integer.parseInt(nitzSubs[0]);            c.set(Calendar.YEAR, year);            // month is 0 based!            int month = Integer.parseInt(nitzSubs[1]) - 1;            c.set(Calendar.MONTH, month);            int date = Integer.parseInt(nitzSubs[2]);            c.set(Calendar.DATE, date);            int hour = Integer.parseInt(nitzSubs[3]);            c.set(Calendar.HOUR, hour);            int minute = Integer.parseInt(nitzSubs[4]);            c.set(Calendar.MINUTE, minute);
如果在系统设置中,用户选择了自动同步网络时间,才会去设置系统时间。
           if (getAutoTime()) {               setAndBroadcastNetworkSetTimeZone(zone.getID());           }           if (getAutoTime()) {setAndBroadcastNetworkSetTime(c.getTimeInMillis());           }
关于NITZ在WIKI上有说明:NITZ, or Network Identity and Time Zone[1], is a mechanism for provisioning local time and date, as well as network provider identity information to mobile devices via a wireless network[2]. NITZ has been part of the official GSM standard since phase 2+ release 96[3]. NITZ is often used to automatically update the system clock of mobile phones.由于NITZ的实现是可选的,如果运营商不支持它,Android手机就无法使用此功能了。此时用最好用SNTP来代替,否则用户会感到迷惑。但Android目前好像并没有这样做,我只找到两处地方调用SntpClient,但它们都没有去设置系统时间。

更多相关文章

  1. Android推送通知指南
  2. Android(安卓)服务器推送技术
  3. Android(安卓)Handler 异步消息处理机制的妙用 创建强大的图片加
  4. 如何使Android应用程序获取系统权限来修改系统时间
  5. android vold学习
  6. Android(安卓)-- Looper.prepare()和Looper.loop() —深入版
  7. Android(安卓)5 消息机制源码分析
  8. android Message的简单实例
  9. Android(安卓)Framework解析

随机推荐

  1. android 深入研究ratingbar自定义
  2. Android短信蠕虫XXshenqi分析
  3. 你真的理解android事件分发机制了吗
  4. Android(安卓)Handler详解
  5. Android(安卓)Robotium的几个小tips
  6. Android开发常见“疑难杂症”解决方案汇
  7. Android(安卓)项目编译过程
  8. Android(安卓)如何建立AIDL
  9. GalHttprequest类库简介——android平台
  10. Android文件系统深入剖析