尝试编写一个可以在多个设备之间同步时间的应用程序。我研究过使用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;
}
}
}