Jak synchronizovat lokální čas uživatele s časem serveru?
sobes.tech AI
Odpověď od AI
Pro přesnou synchronizaci času se serverem na Androidu je vhodné používat protokol NTP (Network Time Protocol). Android má pro to vestavěné mechanismy, ale někdy je třeba čas ručně požadovat nebo použít alternativní přístupy.
Vestavěná synchronizace Android:
Systém Android automaticky synchronizuje čas přes NTP pomocí síťových služeb, obvykle s použitím standardních NTP serverů. Uživatel může v nastavení zvolit možnost "Použít síťový čas". Tato metoda je nejspolehlivější pro běžné scénáře.
Ruční synchronizace (pro zvláštní případy):
Na některých aplikacích nebo zařízeních bez síťového připojení může být potřeba ručně požadovat čas z konkrétního NTP serveru. K tomu lze použít knihovny Apache Commons Net nebo jiné NTP knihovny.
Příklad použití Apache Commons Net:
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
import java.io.IOException;
import java.net.InetAddress;
public class TimeSynchronizer {
private static final String NTP_SERVER = "pool.ntp.org"; // Příklad NTP serveru
public long getSynchronizedTime() {
NTPUDPClient client = new NTPUDPClient();
// Výchozí timeout socketu je 0, nastavíme ho
client.setDefaultTimeout(10000); // 10 sekund
try {
// Zeptáme se na adresu NTP serveru
InetAddress inetAddress = InetAddress.getByName(NTP_SERVER);
// Získáme informace o čase
TimeInfo timeInfo = client.getTime(inetAddress);
// Zpracujeme informace o čase
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
// Spočítáme rozdíl mezi lokálním a serverovým časem
long localTime = System.currentTimeMillis();
long networkTime = timeInfo.getReturnTime();
long roundTripDelay = networkTime - timeInfo.getOriginateTimeStamp().getTime();
long offset = timeInfo.getOffset();
// Synchronizovaný čas je lokální čas + offset
long synchronizedTime = localTime + offset;
return synchronizedTime;
} catch (IOException e) {
e.printStackTrace();
// V případě chyby vraťte -1 nebo vyhoďte výjimku
return -1;
} finally {
client.close();
}
}
}
Synchronizace přes HTTP požadavek (méně přesná):
Lze získat čas ze serveru odesláním HTTP požadavku a analýzou hlavičky Date v odpovědi. Tato metoda je méně přesná než NTP, protože závisí na zpoždění sítě a přesnosti hodin na webovém serveru.
Příklad:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
public class HttpTimeSynchronizer {
private static final String HTTP_URL = "https://www.google.com"; // Příklad URL
public long getSynchronizedTime() {
try {
URL url = new URL(HTTP_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD"); // Pouze hlavičky
connection.connect();
// Získáme hlavičku Date
String dateHeader = connection.getHeaderField("Date");
if (dateHeader != null) {
// Analyzujeme datum z hlavičky. Tento formát se může lišit.
Date date = new Date(dateHeader);
return date.getTime();
} else {
return -1; // Chybí hlavička "Date"
}
} catch (IOException e) {
e.printStackTrace();
return -1; // Chyba při požadavku
}
}
}
Doporučení:
- Většinou se spoléhejte na vestavěnou synchronizaci Androidu.
- Pokud je potřeba vyšší přesnost nebo kontrola nad NTP serverem, použijte knihovny jako Apache Commons Net nebo podobné.
- Synchronizace přes HTTP je méně přesná a nedoporučuje se pro kritické operace závislé na přesném čase.
- Při manuální synchronizaci ošetřete možné chyby sítě a nesprávné odpovědi serveru.
- Synchronizaci provádějte na pozadí, aby nedošlo k blokování UI.