2012-10-25 10 views
14

Tworzę aplikację, w której chcę uzyskać bieżący czas z Internetu.Jak uzyskać aktualny czas z Internetu w Androidzie

Wiem, jak uzyskać czas z urządzenia za pomocą System.currentTimeMillis, a nawet po wielu poszukiwaniach, nie mam pojęcia o tym, jak dostać się z Internetu.

+0

Sprawdź [to] (http://stackoverflow.com/questions/2817475/java-get-current-date-and-time-from-server-not-system-clock) może ci pomóc –

+0

Przepraszam, Sir, ja Jestem nowy dla Androida i ten przykład jest trudny do zrozumienia. – user1726619

Odpowiedz

15

można dostać razem z serwerami czasu w Internecie za pomocą poniższego programu

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 musiałby Apache Commons Net biblioteki dla tej pracy. Download Bibliotekę i dodaj do ścieżki budowania projektu.

(lub można również użyć przyciętego Apache Commons Net Library tutaj. https://www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar To wystarczy, aby uzyskać czas z internetu)

2.Run program. Otrzymasz czas wydrukowany na konsoli.

+0

Czy możesz podać mi nazwę niezawodnego serwera czasu? – user1726619

+1

@ user1726619 Wszystkie wymienione serwery są niezawodne, ponieważ są obsługiwane przez NIST. Ten, którego używałem, działa dobrze. Ale jak mówi strona NIST, nie powinieneś zakodować adresów URL. Możesz dostarczyć 4 lub 5 serwerów czasu w pliku właściwości lub sqlite db. Następnie zacznij od pierwszego adresu URL i poczekaj na wynik (lub limit czasu). Jeśli został przekroczony limit czasu, spróbuj użyć następnego linku i tak dalej. Jeśli wszystkie łącza się nie powiodą (bardzo rzadko), możesz wyświetlić wiadomość użytkownikowi. (lub zacznij od początku) – sunil

+1

Nie otrzymuję takiego adresu znalezionego wyjątku na tym adresie internetowym. – user1726619

1

Będziesz potrzebować dostępu do usługi internetowej, która zapewnia bieżący czas w formacie XML lub JSON.

Jeśli nie możesz znaleźć tego typu usługi, możesz przeanalizować czas ze strony internetowej, np. http://www.timeanddate.com/worldclock/ lub hostować własną usługę czasu na serwerze przy użyciu prostej strony PHP na przykład.

Sprawdź JSoup dla parsowania stron HTML.

+0

Poinformuj mnie, proszę, jak przeanalizować czas z tej strony. To będzie bardzo pomocne dla początkujących jak ja. Dzięki za to. – user1726619

+0

Jego usługi są bardzo kosztowne. Czy możesz mi podać link do jakiegoś dostawcy usług APi w czasie wolnym? – user1726619

+0

Zapoznaj się z dokumentacją JSoup, wypróbuj kod i skontaktuj się z nami, jeśli napotkasz problemy. –

7

Oto metoda, która stworzyłem dla was można to wykorzystać w kodzie

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

Ładny przykład kodu. Czy jesteś jednak pewien, że masz uprawnienia do używania identyfikatora aplikacji 'YahooDemo' w aplikacji produkcyjnej? –

+0

Ya, dostałem go stąd http://developer.yahoo.com/util/timeservice/V1/getTime.html potrzebujesz identyfikatora aplikacji, http://developer.yahoo.com/faq/index .html # appid Użyłem domyślnego linku –

+0

Użyłem tej metody. Ale to bardzo niewiarygodne! Często nie można uzyskać czasu – XXX

1

Myślę, że najlepszym rozwiązaniem jest użycie SNTP, w szczególności kod klienta SNTP od samego Androida, na przykład : http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/net/SntpClient.java/

Wierzę, że Android używa SNTP do automatycznej aktualizacji daty/czasu, gdy sieć komórkowa jest niedostępna (np. Tablety Wi-Fi).

Myślę, że jest to lepsze niż inne rozwiązania, ponieważ używa SNTP/NTP zamiast protokołu czasu (RFC 868) używanego przez Apache TimeTCPClient. Nie wiem nic złego o RFC 868, ale NTP jest nowsza i wydaje się, że go przekroczyła i jest szerzej stosowana. Uważam, że urządzenia z Androidem, które nie mają komórkowej funkcji, korzystają z NTP.

Ponadto, ponieważ używa gniazd. Niektóre z proponowanych rozwiązań wykorzystują protokół HTTP, więc tracą coś ze swojej dokładności.

1

Nic z powyższego nie zadziałało ode mnie. Tak właśnie skończyłem (z Volley);
Ten przykład również konwertuje do innej strefy czasowej.

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; 

importu Volley w Gradle:

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

Ale aby pobrać odpowiedź z powyższego api, zajmie to kilka sekund, prawda? co z upływem czasu ... ?? – shobhan

+0

To było wystarczająco dobre dla mnie – user3734429

+3

Przyzwoite rozwiązanie, jeśli nie przeszkadza nam kilka sekund niedokładności. Dobry interes. Ale zastanawiam się, kto popiera timeapi.org i jak prawdopodobne jest, że może przejść w tryb offline. – rpattabi

0

Jeśli nie dbać o dokładność milisekundy, a jeśli już używasz google Firebase lub nie przeszkadza używając go (stanowią one bezpłatne Poziom), sprawdź to: https://firebase.google.com/docs/database/android/offline-capabilities#clock-skew

Zasadniczo baza danych bazy danych Firebase zawiera pole, które zapewnia wartość przesunięcia między czasem urządzenia i czasem serwera Firebase.Możesz użyć tego offsetu, aby uzyskać aktualny czas.

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"); 
    } 
}); 

Tak jak powiedziałem, będzie niedokładne w oparciu o opóźnienie sieci.

+0

To pole zostanie zapisane w pamięci podręcznej, więc jeśli chcesz uzyskać tę wartość wiele razy, musisz wykonać 'FirebaseDatabase.getInstance(). GoOffline()' i 'goOnline()' – Niels

+0

Oh! Dzięki, że dałeś mi znać. – rpattabi

Powiązane problemy