移动设备之间的时间同步

时间:2015-08-13 19:52:57

标签: android time gps ntp

尝试编写一个可以在多个设备之间同步时间的应用程序。我研究过使用gps,设备和NTP时间。根据我的理解,我从gps获得的时间是设备接收位置信息的时间,因此取决于设备时间。由于显而易见的原因,系统时间不起作用,因此我尝试了NTP时间。我有2个设备上显示所有3个,我不知道为什么NTP不起作用。任何人都可以向我解释为什么或我做错了什么? (我为一些糟糕的编码实践道歉,只是为了测试目的将它们放在一起)

package temp.gpstime;

import android.app.Activity;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class MainActivity extends Activity implements LocationListener,
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

    private long mLastUpdateTime;
    private Location currentLocation;
    private LocationRequest mLocationRequest;
    private GoogleApiClient mGoogleApiClient;
    private static final String TAG = "MainActivity";
    private static final long INTERVAL = 1000 * 5;
    private static final long FATEST_INTERVAL = 1000 * 5;
    private boolean hasFirst = false;
    private int count = 0;
    private Location first;
    long NTPReturnedTime;
    boolean setTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(TAG, "On Create . . . . .");
        final TextView txtTimeDiff = (TextView) findViewById(R.id.timedifference);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        createLocationRequest();

        final Button updateDifference = (Button) findViewById(R.id.Update);
        updateDifference.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                long timer = System.currentTimeMillis() - mLastUpdateTime;
                long difference = System.currentTimeMillis() - currentLocation.getTime() - timer;
                txtTimeDiff.setText(difference + "");
            }
        });

        new getTimeNTP().execute();
        Thread myThread = null;

        Runnable myRunnableThread = new CountDownRunner();
        myThread = new Thread(myRunnableThread);
        myThread.start();
    }

    public void doWork() {
        runOnUiThread(new Runnable() {
            public void run() {
                try {
                    TextView txtCurrentGPSTime = (TextView) findViewById(R.id.GpsTime);
                    TextView txtCurrentDeviceTime = (TextView) findViewById(R.id.DeviceTime);
                    TextView txtFirstFix = (TextView) findViewById(R.id.gpsfixtime);
                    TextView txtFirstSysFix = (TextView) findViewById(R.id.systemFixTime);
                    TextView txtTimeDiff = (TextView) findViewById(R.id.timedifference);
                    TextView txtNTPtime = (TextView) findViewById(R.id.NTPTime);

                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                    sdf.setTimeZone(TimeZone.getTimeZone("gmt"));

                    String gpsTime = sdf.format(new Date(currentLocation.getTime()));
                    txtCurrentGPSTime.setText(gpsTime);

                    String deviceTime = sdf.format(System.currentTimeMillis());
                    txtCurrentDeviceTime.setText(deviceTime);

                    if(setTime) {
                        String NTPTimeFormat = sdf.format(new Date(NTPReturnedTime));
                        txtNTPtime.setText(NTPTimeFormat);
                        NTPReturnedTime += 50;
                    }

                    if (!hasFirst && first != null) {
                        txtFirstFix.setText(sdf.format(new Date(first.getTime())));
                        txtFirstSysFix.setText(sdf.format(new Date(System.currentTimeMillis())));
                        txtTimeDiff.setText((System.currentTimeMillis() - first.getTime()) + "");
                        hasFirst = true;
                    }

                } catch (Exception e) {
                }
            }
        });
    }

    class CountDownRunner implements Runnable {
        // @Override
        public void run() {
            Log.e("Main", "Inside Run");
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    doWork();
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } catch (Exception e) {
                }
            }
        }
    }

    protected  void createLocationRequest(){
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FATEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.e(TAG, "onConnected: Connected - " + mGoogleApiClient.isConnected());
        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        Log.e(TAG, "Location update started ");
    }

    @Override
    public void onConnectionSuspended(int i) {
        stopLocationUpdates();
        Log.e(TAG, "On Connection Suspended " + mGoogleApiClient.isConnected());
        Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.e(TAG, "Connection failed " + connectionResult.toString());
        stopLocationUpdates();
        Log.e(TAG, "onConnectionFailed " + mGoogleApiClient.isConnected());
        Toast.makeText(getApplicationContext(), "No Network Connection", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onLocationChanged(Location location) {
       // Log.e(TAG, "Firing onLocationChanged.........");
        mLastUpdateTime = System.currentTimeMillis();
        if(count == 0){
            first = location;
            count++;
        }
        currentLocation = location;
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        Log.e(TAG, "Location update stopped");
    }

    @Override
    public void onStart() {
        super.onStart();

        mGoogleApiClient.connect();
        Log.e(TAG, "MainActivity Started, GoogleApi Connection:  " + mGoogleApiClient.isConnected());
    }

    public class getTimeNTP extends AsyncTask<Void, Void, Void> {
        InetAddress inetAddress;
        private String TIME_SERVER = "time-a.nist.gov";
        TimeInfo timeInfoServer;
        NTPUDPClient timeClient;
        long returnTime;
        SimpleDateFormat sdf;

        @Override
        protected Void doInBackground(Void... params) {
            timeClient = new NTPUDPClient();
            try {
                inetAddress = InetAddress.getByName(TIME_SERVER);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }

            try {
                timeInfoServer = timeClient.getTime(inetAddress);
                returnTime = timeInfoServer.getReturnTime();
                Log.e("Main", returnTime + "");
            } catch (IOException e) {
                e.printStackTrace();
            }

            NTPReturnedTime = returnTime;
            setTime = true;

            return null;
        }
    }
}

0 个答案:

没有答案