Conhecem alguma forma de fazer um relógio interno perfeito?, eu tentei fazer da seguinte forma, peguei a data/hora exata do telefone em Milissegundos e comecei a contar essa hora adicionando a ela mais 1000(1sg) a cada segundo, mas parece que o ciclo não é o mesmo assim sempre depois de um tempo o meu horário sempre esta diferente, teoricamente o meu horário deveria estar igual ao do dispositivo, sabem de alguma alternativa?, a intenção é ter um relógio que sempre mostre a verdadeira hora, independente da hora do celular. Uso NTPUDPClient pedindo a hora para “time.nist.gov”, que me retorna a hora correta no momento, mas nem sempre terá internet quando eu quiser.
Estou fazendo um rastreador por celular que fica pegando as coordenadas de GPS a cada N tempo e guardando isso em LOG junto com a hora que ele pegou dessa localização, então precisaria de um relógio MEU, que estaria correto, já que do celular o usuário pode mudar.
Aki esta o serviço que criei,
public class CustomClock extends Service {
private final String TAG = this.getClass().getSimpleName();
private long timeCustomInMilliseconds = 0;
CountDownTimer countDownTimer = null;
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
private boolean isNotGettingTime = true;
private final IBinder mBinder = new LocalBinder();
public CustomClock() {
}
@Override
public void onCreate() {
Log.i(TAG, "Service CustomClock onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service CustomClock started");
return START_STICKY;
}
class LocalBinder extends Binder {
CustomClock getService() {
// Return this instance of LocalService so clients can call public methods
return CustomClock.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void setCounter() {
Log.i(TAG,"setCounter");
if(countDownTimer != null){
countDownTimer.cancel();
}
countDownTimer = new CountDownTimer(86400000 , 1000) {//24 horas, 1s
public void onTick(long millisUntilFinished) {
Calendar cal = Calendar.getInstance();
long systemTime = System.currentTimeMillis();
Log.i(TAG,"TIME_COUNTER CUSTOM: " + timeCustomInMilliseconds + " DEVICE: "
+ systemTime
+ " DIF: + " + (systemTime - timeCustomInMilliseconds ));
timeCustomInMilliseconds += 1000;//adiciona 1s a contagem
}
public void onFinish() {
countDownTimer.start();
}
}.start();
}
public long getTimeCustomInMilliseconds() {
return timeCustomInMilliseconds;
}
public boolean isNotGettingTime(){
return this.isNotGettingTime;
}
public void setTimeCustomInMilliseconds(long timeCustomInMilliseconds) {
this.timeCustomInMilliseconds = timeCustomInMilliseconds;
this.isNotGettingTime = true;
}
public void setTimeFromNet(){
this.isNotGettingTime = false;
final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
isNotGettingTime = false;
if(getTimeCustomInMilliseconds() != 0 && getTimeCustomInMilliseconds() != -1){
setCounter();
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
setTimeCustomInMilliseconds(getTimeInNet().time);
Message message = mHandler.obtainMessage(0, 0);
message.sendToTarget();
}
}).start();
}
private TimeResult getTimeInNet() {
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress;
timeClient.setDefaultTimeout(10000);
try {
inetAddress = InetAddress.getByName(Constants.TIME_SERVERS[1]);// a.st1.ntp.br
} catch (UnknownHostException e) {
return new TimeResult(FAILURE_RESULT, -1, e.getMessage());
}
TimeInfo timeInfo;
try {
timeInfo = timeClient.getTime(inetAddress);
} catch (IOException e) {
return new TimeResult(FAILURE_RESULT, -1, e.getMessage());
}
long time = timeInfo.getMessage().getTransmitTimeStamp().getTime(); //data/hora em millisegundos do servidor
long timeSystem= System.currentTimeMillis();//Busca hoario atual em millisegundos do telefone(fazer comparacao)
Log.i(TAG,"GET_TIME_FROM_NET -> NET: " + time + " DEVICE: "
+ timeSystem
+ " DIF: + " + (timeSystem - time ));
timeClient.close();
return new TimeResult(SUCCESS_RESULT, time, "");
}
private class TimeResult {
int resultCode;
String failureMessage;
long time;
TimeResult(int resultCode, long time, String failureMessage) {
this.resultCode = resultCode;
this.time = time;
this.failureMessage = failureMessage;
}
}
@Override
public void onDestroy() {
super.onDestroy();
if(countDownTimer != null){
countDownTimer.cancel();
}
}
}
Para ativá-lo e usá-lo uso,
private CustomClock customClock;
boolean isCustomClockBind = false;
@Override
protected void onStart() {
super.onStart();
initAndBindClock();
}
private void initAndBindClock(){
startService(new Intent(getBaseContext(), CustomClock.class));
Intent intent = new Intent(this, CustomClock.class);
bindService(intent, mConnection, 0);
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
CustomClock.LocalBinder binder = (CustomClock.LocalBinder) service;
customClock = binder.getService();
isCustomClockBind = true;
if(customClock.isNotGettingTime()){
customClock.setTimeFromNet();
}
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
isCustomClockBind = false;
}
};