http://www.oschina.net/question/54100_31740
感谢博主的第一种方法,第二种方法没有尝试,
工作流程如下记录:
1. 有wifi的情况下获取ntp时间
2. 用获取NTP时间Android已经有现成的类D:\work_java\Android\sdk-meng\sources\android-19\android\net\SntpClient.java, 但是 是隐形的类.
源码中可见{@hide} 表示隐形类不能直接调用.所以要想其他的办法调用
3. 隐形的api在window的编译环境下不能直接调用包括以下几个办法:
- 直接复制SntpClient.java整个类到自己的工程下
- 源码编译工程
- java反射调用
4. 本次用java反射方法调用SntpClient类, 新编写类SntpTime
5. 在适当地方调用此类 之后执行SystemClock.setCurrentTimeMillis(sntpTime);
6. 修改AndroidManifest.xml 在manifest添加 android:sharedUserId="android.uid.system"在win编译不通过提示错误

"http://schemas.android.com/apk/res/android"    package="com.csctek.android.iserver.services"    android:versionCode="1"    android:versionName="1.0"     android:sharedUserId="android.uid.system">
  1. 确保Linux下的app编译路径下的Android.mk 文件 下 LOCAL_CERTIFICATE := platform
  2. 源码下编译 mm
  3. 自测可修改系统时间
  4. 测试NTP服务器 123.124.209.75 默认端口123
  5. 没有执行权限的调用函数SystemClock.setCurrentTimeMillis(sntpTime);无论怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中总会得到”Unable to open alarm driver: Permission denied “
package com.android.myapp.sntptime;import android.os.Handler;import android.os.Message;import android.os.SystemClock;import android.util.Log;import java.lang.reflect.Method;import java.util.Date;/** * Created by user on 2016/11/28. */public class SntpTime {    private String TAG = "SntpTime";    private String mIp;    private int mTimeOut;    private Handler mOtherHandler;    private int mHandlerWhatNumber;    // 时间获取ip地址 // socket超时时间 // 消息句柄// 消息标号自定义What数字    public SntpTime (String ip, int timeOut, Handler handler, int handlerWhatNumber) {        this.mIp = ip;        this.mTimeOut = timeOut;        this.mOtherHandler = handler;        this.mHandlerWhatNumber = handlerWhatNumber;        Log.i(TAG, "SntpTime: " + mIp + " " + mTimeOut + " " + mHandlerWhatNumber);    }    public void getTime() {        new Thread() {            public void run() {                //使用隐形类                try {                    Class C;                    //通过名字查找类 class                    C = Class.forName("android.net.SntpClient");                    Log.i(TAG, "class is " + C);                    Object obj = C.newInstance();                    try {                        //函数参数 2个 requestTime                        //根据名字和参数个数查找函数                        Method m = C.getMethod("requestTime", new Class[]{String.class, int.class});                        //参数值以数组的形式传入,格式与Class一样                        //调用函数                        Object o = m.invoke(obj, new Object[]{mIp, mTimeOut});                        //返回值转换                        boolean b = (Boolean)o;                        Log.i(TAG, "return is " + b);                        if (b) {                            //SntpClient.getNtpTime() //return time value computed from NTP server response                            Method mGetNtpTime = C.getMethod("getNtpTime", new Class[]{});                            Object oGetNtpTime = mGetNtpTime.invoke(obj, new Object[]{});                            Long ntpTime = (Long)oGetNtpTime;                            Log.i(TAG, "ntpTime is " + ntpTime);                            //SntpClient.getNtpTimeReference() == SystemClock.elapsedRealtime()                            //reference clock corresponding to the NTP time                            Method mGetNtpTimeReference = C.getMethod("getNtpTimeReference", new Class[]{});                            Object oGetNtpTimeReference = mGetNtpTimeReference.invoke(obj, new Object[]{});                            Long ntpTimeReference = (Long)oGetNtpTimeReference;                            Log.i(TAG, "ntpTimeReference is " + ntpTimeReference);                            ////////////////////////////////                            Log.i(TAG, "SystemClock.elapsedRealtime() is "+ SystemClock.elapsedRealtime());                            Log.i(TAG, "System.currentTimeMillis() is "+ System.currentTimeMillis());                            Date test0 = new Date(ntpTime);                            Log.i(TAG, "ntpTime is Date.toString()" + test0.toString());                            Date test1 = new Date(System.currentTimeMillis());                            Log.i(TAG, "System.currentTimeMillis() is Date.toString()" + test1.toString());                            //很多网上的公式我这里测试返回的结果是错误的如: long now = client.getNtpTime() + System.nanoTime() / 1000 - client.getNtpTimeReference();                             //本人这个计算公式是源码SntpClient.java源码注释中提供的,可自己查看                            long nowTime = ntpTime + SystemClock.elapsedRealtime() - ntpTimeReference;                            updateTimeAndDate(nowTime);                            Date currentTime = new Date(nowTime);                            Message toOtherHandler = new Message();                            toOtherHandler.what = mHandlerWhatNumber;                            toOtherHandler.obj = nowTime;                            Log.i(TAG, "mHandlerWhatNumber is "+ mHandlerWhatNumber + "time : " + currentTime.toString());                            mOtherHandler.sendMessage(toOtherHandler);                        }                    } catch (Exception e) {                        e.printStackTrace();                        Log.e(TAG, "GetClass SntpClient is error! two ");                    }                } catch (Exception e) {                    e.printStackTrace();                    Log.e(TAG, "GetClass SntpClient is error! one ");                }            }        }.start();    }private void updateTimeAndDate(Long sntpTime) {        long systemTime = System.currentTimeMillis();        Log.i(ISSERVICE, "Time////System.currentTimeMillis() is " + System.currentTimeMillis());        Log.i(ISSERVICE, "Time////sntpTime is " + sntpTime);        Log.i(ISSERVICE, "Time////(systemTime - sntpTime) = " + (systemTime - sntpTime));        //if((systemTime - sntpTime >= 1000*60 ) || (systemTime - sntpTime <= -1000*60) ) {            //时间格式修改            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd.HHmmss");//yyyy-MM-dd HH:mm:ss            String format = df.format(new Date(sntpTime));            Log.i(TAG, "Time////format is " + format);            boolean b = SystemClock.setCurrentTimeMillis(sntpTime);            Log.i(TAG, "Time////System.currentTimeMillis() is " + System.currentTimeMillis() + "return currentTimeMillis bool = " + b);// }    }}

SntpTime类中有构造函数传入一个Handler, 所以我们通过Handler得到msg也就是NTP上的时间, 传递给主调函数,给系统设置时间

private void startSntpTime() {//参数1 表示Ip//参数2 超时时间//参数3 Handler//参数4 传入的Handler.What值        SntpTime currentTime = new SntpTime(ISGlobleBaseData.SNTP_TIME_IP, 30000, mHandler, ISServiceHandleMessage.SNTP_TIME_HANDLER);        currentTime.getTime();    }/////////////////////////////////Handler消息分类 //Long这里一定要用 Long 代替long 否则linux源码mm编译的时候会报错case ISServiceHandleMessage.SNTP_TIME_HANDLER:                Long time = (Long)msg.obj;                Log.i(ISSERVICE, "time//// = " + String.valueOf(time));                break;///////////////////////////////////////////////

更多相关文章

  1. Android中调用C++函数的一个简单Demo
  2. Android的参数大致分成两块:系统服务参数和平台系统信息。
  3. 使用android中drawline函数无法绘制水平线的解决办法
  4. WebView与Javascript交互(相互调用参数、传值)
  5. Android中的时间自动更新
  6. Android 设置合理的定时器隔一段时间执行某段程序
  7. Android如何在三年时间里征服移动世界的
  8. Android 获取View的位置参数:x,y和相对父容器的偏移量以及中心点

随机推荐

  1. 数据的异构实战(一) 基于canal进行日志的订
  2. 微服务架构下的分布式限流方案全解析
  3. 面试官:你了解过Redis对象底层实现吗
  4. 多线程基础体系知识清单
  5. 基于golang分布式爬虫系统的架构体系v1.0
  6. 面试官:你能谈谈Dubbo SPI扩展原理吗?
  7. lnmp一键安装包搭建lnmp环境,二种方式
  8. Django 中间件
  9. 序列化框架的选型和比对
  10. 5-5(linux常见指令)