2012-10-25 12 views
14

Sto creando un'app in cui voglio ottenere l'ora corrente da internet.Come ottenere l'ora corrente da internet in Android

So come ottenere l'ora dal dispositivo utilizzando System.currentTimeMillis e anche dopo aver cercato molto, non ho avuto alcuna idea su come ottenerlo da internet.

+0

Controlla [questo] (http://stackoverflow.com/questions/2817475/java-get-current-date-and-time-from-server-not-system-clock) potrebbe aiutarti –

+0

Scusa Signore, io Sono nuovo di Android e quell'esempio è difficile da capire. – user1726619

risposta

15

È possibile ottenere il tempo dagli assistenti di tempo internet utilizzando il programma di seguito

import java.io.IOException; 

import org.apache.commons.net.time.TimeTCPClient; 

public final class GetTime { 

    public static final void main(String[] args) { 
     try { 
      TimeTCPClient client = new TimeTCPClient(); 
      try { 
       // Set timeout of 60 seconds 
       client.setDefaultTimeout(60000); 
       // Connecting to time server 
       // Other time servers can be found at : http://tf.nist.gov/tf-cgi/servers.cgi# 
       // Make sure that your program NEVER queries a server more frequently than once every 4 seconds 
       client.connect("nist.time.nosc.us"); 
       System.out.println(client.getDate()); 
      } finally { 
       client.disconnect(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

1.You avrebbe bisogno Apache Commons Net libreria per far funzionare tutto questo. Download la libreria e aggiungere al percorso di costruzione del progetto.

(In alternativa, è anche possibile utilizzare il rifilato Apache Commons Net Library qui:. https://www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar Questo è sufficiente per ottenere il tempo da internet)

2.Run il programma. Otterrai l'ora stampata sulla tua console.

+0

Puoi dirmi il nome di un qualsiasi server orario affidabile? – user1726619

+1

@ user1726619 tutti i server elencati sono affidabili, poiché è gestito da NIST. Quello che ho usato sta funzionando bene. Ma come dice il sito NIST, non devi inserire hardcode in alcun URL. È possibile fornire 4 o 5 server temporali in un file di proprietà o in un db sqlite. Quindi inizia dal primo url e attendi il risultato (o il timeout). Se è scaduto, prova il collegamento successivo e così via. Se tutti i collegamenti falliscono (possibilità molto rara), puoi mostrare un messaggio all'utente. (o inizio dall'inizio) – sunil

+1

Non ricevo alcuna eccezione per questo indirizzo su questo indirizzo web. – user1726619

1

È necessario avere accesso a un servizio web che fornisce l'ora corrente in formato XML o JSON.

Se non si trova questo tipo di servizio, è possibile analizzare l'ora da una pagina Web, ad esempio http://www.timeanddate.com/worldclock/, o ospitare il proprio servizio orario su un server utilizzando una semplice pagina PHP, ad esempio.

Scopri JSoup per l'analisi delle pagine HTML.

+0

Per favore dimmi signore come analizzare il tempo da questo sito Web. Sarà molto utile per un principiante come me. Grazie in anticipo. – user1726619

+0

I suoi servizi sono molto costosi. Può darmi per favore il link di qualche fornitore di servizi API a tempo libero? – user1726619

+0

Si prega di dare un'occhiata alla documentazione di JSoup, provare un po 'di codice e tornare da noi se si riscontrano problemi. –

7

Ecco un metodo che ho creato per voi è possibile utilizzare questo nel codice

public String getTime() { 
try{ 
    //Make the Http connection so we can retrieve the time 
    HttpClient httpclient = new DefaultHttpClient(); 
    // I am using yahoos api to get the time 
    HttpResponse response = httpclient.execute(new 
    HttpGet("http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo")); 
    StatusLine statusLine = response.getStatusLine(); 
    if(statusLine.getStatusCode() == HttpStatus.SC_OK){ 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     response.getEntity().writeTo(out); 
     out.close(); 
     // The response is an xml file and i have stored it in a string 
     String responseString = out.toString(); 
     Log.d("Response", responseString); 
     //We have to parse the xml file using any parser, but since i have to 
     //take just one value i have deviced a shortcut to retrieve it 
     int x = responseString.indexOf("<Timestamp>"); 
     int y = responseString.indexOf("</Timestamp>"); 
     //I am using the x + "<Timestamp>" because x alone gives only the start value 
     Log.d("Response", responseString.substring(x + "<Timestamp>".length(),y)); 
     String timestamp = responseString.substring(x + "<Timestamp>".length(),y); 
     // The time returned is in UNIX format so i need to multiply it by 1000 to use it 
     Date d = new Date(Long.parseLong(timestamp) * 1000); 
     Log.d("Response", d.toString()); 
     return d.toString() ; 
    } else{ 
     //Closes the connection. 
     response.getEntity().getContent().close(); 
     throw new IOException(statusLine.getReasonPhrase()); 
    } 
}catch (ClientProtocolException e) { 
Log.d("Response", e.getMessage()); 
}catch (IOException e) { 
Log.d("Response", e.getMessage()); 
} 
return null; 
} 
+0

Esempio di codice piacevole. Tuttavia, sei sicuro di essere autorizzato a utilizzare l'ID app 'YahooDemo' in un'applicazione di produzione? –

+0

Ya, l'ho preso da qui http://developer.yahoo.com/util/timeservice/V1/getTime.html è necessario disporre di un ID app, http://developer.yahoo.com/faq/index .html # appid Ho usato il collegamento predefinito –

+0

Ho usato questo metodo. Ma è molto inaffidabile! Spesso non è possibile ottenere il tempo – XXX

1

Penso che la soluzione migliore è quella di utilizzare SNTP, in particolare il codice del client SNTP da Android stesso, ad esempio, : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/net/SntpClient.java/

credo Android utilizza SNTP per gli aggiornamenti automatici data/ora di una rete cellulare non è disponibile (ad esempio compresse wifi).

Penso che sia meglio delle altre soluzioni perché utilizza SNTP/NTP piuttosto che il protocollo Time (RFC 868) utilizzato da Apache TimeTCPClient. Non so nulla di negativo su RFC 868, ma NTP è più recente e sembra averlo superato ed è più ampiamente utilizzato. Credo che i dispositivi Android che non hanno cellulare utilizzino NTP.

Inoltre, poiché utilizza prese. Alcune delle soluzioni proposte utilizzano HTTP in modo che perderanno qualcosa nella loro accuratezza.

1

Niente da quanto sopra ha funzionato da me. Questo è quello che ho finito con (con Volley);
Questo esempio converte anche in un altro fuso orario.

Long time = null; 
    RequestQueue queue = Volley.newRequestQueue(this); 
    String url ="http://www.timeapi.org/utc/now"; 

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 
      new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        try { 
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 
         simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
         Date date = simpleDateFormat.parse(response); 

         TimeZone tz = TimeZone.getTimeZone("Israel"); 
         SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
         destFormat.setTimeZone(tz); 

         String result = destFormat.format(date); 

         Log.d(TAG, "onResponse: " + result.toString()); 
        } catch (ParseException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      Log.w(TAG, "onErrorResponse: "+ error.getMessage()); 
     } 
    }); 
    queue.add(stringRequest); 
    return time; 

Importa Volley in Gradle:

compile 'com.android.volley:volley:1.0.0' 
+0

Ma per recuperare la risposta dalla API precedente, ci vorranno pochi secondi, giusto? che ne dici del tempo trascorso .. ?? – shobhan

+0

È stato abbastanza buono per me – user3734429

+3

Soluzione decente se non ci importa pochi secondi di imprecisione. Buon compromesso. Ma mi chiedo chi appoggi timeapi.org e quanto è probabile che possa andare offline. – rpattabi

0

Se non si cura per la precisione millisecondo, e se si sta già utilizzando Google Firebase o non dispiace ad usarlo (che forniscono un livello gratuito), verificarlo: https://firebase.google.com/docs/database/android/offline-capabilities#clock-skew

In sostanza, il database Firebase ha un campo che fornisce il valore di offset tra l'ora del dispositivo e l'ora del server Firebase.È possibile utilizzare questo offset per ottenere l'ora corrente.

DatabaseReference offsetRef = FirebaseDatabase.getInstance().getReference(".info/serverTimeOffset"); 
offsetRef.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot snapshot) { 
    double offset = snapshot.getValue(Double.class); 
    double estimatedServerTimeMs = System.currentTimeMillis() + offset; 
    } 

    @Override 
    public void onCancelled(DatabaseError error) { 
    System.err.println("Listener was cancelled"); 
    } 
}); 

Come ho detto, sarà impreciso in base alla latenza della rete.

+0

Questo campo verrà memorizzato nella cache, quindi se si desidera ottenere questo valore più volte, è necessario eseguire 'FirebaseDatabase.getInstance(). GoOffline()' e 'goOnline()' – Niels

+0

Oh! Grazie per avermi fatto sapere. – rpattabi

Problemi correlati