在安卓中同步服务器时间有多种方法,我来为你详细介绍几种常见的方案:
1. 使用 HTTP 请求获取服务器时间
public class TimeSyncUtils {
public static long getServerTime(String url) {
try {
URL serverUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) serverUrl.openConnection();
connection.setRequestMethod("HEAD");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
long serverTime = connection.getDate();
connection.disconnect();
return serverTime;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
// 使用示例
public static void syncTime() {
long serverTime = getServerTime("https://your-server.com/api");
if (serverTime > 0) {
long deviceTime = System.currentTimeMillis();
long timeDiff = serverTime - deviceTime;
// 保存时间差,在应用中使用
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putLong("time_offset", timeDiff).apply();
}
}
// 获取校准后的时间
public static long getAdjustedTime() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
long offset = prefs.getLong("time_offset", 0);
return System.currentTimeMillis() + offset;
}
}2. 使用 NTP 协议同步时间(推荐)
添加依赖:
implementation 'commons-net:commons-net:3.8.0'
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
public class NTPTimeSync {
public static long getNTPTime() {
NTPUDPClient client = new NTPUDPClient();
client.setDefaultTimeout(10000);
try {
client.open();
InetAddress hostAddr = InetAddress.getByName("pool.ntp.org");
TimeInfo info = client.getTime(hostAddr);
info.computeDetails();
Long offset = info.getOffset();
Long delay = info.getDelay();
if (offset != null) {
return System.currentTimeMillis() + offset;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
client.close();
}
return -1;
}
}3. 使用 SNTP 客户端
import android.os.SystemClock;
public class SntpClient {
private static final int ORIGINATE_TIME_OFFSET = 24;
private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;
private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;
public boolean requestTime(String host, int timeout) {
try {
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(timeout);
InetAddress address = InetAddress.getByName(host);
byte[] buffer = new byte[NTP_PACKET_SIZE];
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0] = (NTP_MODE_CLIENT | (NTP_VERSION << 3));
long requestTime = System.currentTimeMillis();
long requestTicks = SystemClock.elapsedRealtime();
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime);
socket.send(request);
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
long responseTicks = SystemClock.elapsedRealtime();
long responseTime = requestTime + (responseTicks - requestTicks);
long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);
long clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime)) / 2;
// 保存时间偏移量
saveTimeOffset(clockOffset);
socket.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private long readTimeStamp(byte[] buffer, int offset) {
long seconds = read32(buffer, offset);
long fraction = read32(buffer, offset + 4);
return ((seconds - 2208988800L) * 1000) + ((fraction * 1000L) / 0x100000000L);
}
private void writeTimeStamp(byte[] buffer, int offset, long time) {
long seconds = time / 1000L + 2208988800L;
long fraction = ((time % 1000L) * 0x100000000L) / 1000L;
write32(buffer, offset, (int) seconds);
write32(buffer, offset + 4, (int) fraction);
}
private long read32(byte[] buffer, int offset) {
byte b0 = buffer[offset];
byte b1 = buffer[offset + 1];
byte b2 = buffer[offset + 2];
byte b3 = buffer[offset + 3];
return ((b0 & 0xFF) << 24) | ((b1 & 0xFF) << 16) |
((b2 & 0xFF) << 8) | (b3 & 0xFF);
}
private void write32(byte[] buffer, int offset, int value) {
buffer[offset] = (byte) ((value >> 24) & 0xff);
buffer[offset + 1] = (byte) ((value >> 16) & 0xff);
buffer[offset + 2] = (byte) ((value >> 8) & 0xff);
buffer[offset + 3] = (byte) (value & 0xff);
}
private void saveTimeOffset(long offset) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putLong("ntp_time_offset", offset).apply();
}
}4. 定期同步的 Service
public class TimeSyncService extends Service {
private static final long SYNC_INTERVAL = 30 * 60 * 1000; // 30分钟
private Handler handler = new Handler();
private Runnable syncRunnable = new Runnable() {
@Override
public void run() {
syncTimeWithServer();
handler.postDelayed(this, SYNC_INTERVAL);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.post(syncRunnable);
return START_STICKY;
}
private void syncTimeWithServer() {
// 使用上述任意方法同步时间
long serverTime = NTPTimeSync.getNTPTime();
if (serverTime > 0) {
// 保存时间偏移或直接使用
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putLong("last_sync_time", System.currentTimeMillis())
.putLong("time_offset", serverTime - System.currentTimeMillis())
.apply();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}5. 常用 NTP 服务器地址
public class NtpServers {
public static final String[] SERVERS = {
"pool.ntp.org",
"time.google.com",
"time.apple.com",
"time.windows.com",
"cn.pool.ntp.org", // 中国地区
"ntp.aliyun.com" // 阿里云
};
}注意事项:
1、权限要求:需要网络权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2、时间校准:普通应用无法修改系统时间,只能记录偏移量在应用内使用
3、网络延迟:需要考虑网络延迟对时间同步精度的影响
4、定期同步:建议定期同步以保持时间准确性
选择哪种方法取决于你的具体需求:如果只需要相对时间,HTTP 方法足够;如果需要高精度时间,推荐使用 NTP 协议。
文章摘自:https://idc.huochengrm.cn/fwq/16753.html
评论
杞鹤骞
回复安卓手机可通过设置中的时间与日期选项,选择同步网络时间并自动与服务器校准。
彤芸若
回复在安卓中,可以通过HTTP请求、NTP协议、SNTP客户端、Service定期同步等方式来同步服务器时间,具体选择哪种方法取决于应用需求,例如精度、实时性等。