[英]How can I sync the system clocks of two or more android phones?
我正在嘗試開發一個應用程序,允許其他Android手機充當揚聲器,從而創建一個類似於派對的派對。 該應用程序類似於三星提供的群游功能。
為了實現這個功能,我決定執行以下步驟 -
**面臨的問題 - **實現之后,我注意到兩個Android設備都有不同的系統時間,因此我使用使用NTP同步時間的ClockSync App同步了系統時間。 我不希望我的用戶使用需要root訪問權限的第三方應用。 那我怎么能同步兩部Android手機的時鍾呢? 我該如何解決這個問題?
編輯 - 我在AsyncTask
類下面使用來計算NTP時鍾和本地時鍾之間的差異。
public class offSetAsyncTask extends AsyncTask<Void,Void,Double> {
private String serverName;
private double localClockOffset;
private double destinationTimestamp;
private double roundTripDelay;
double total = 0;
Context context;
double avg;
@Override
protected Double doInBackground(Void... params) {
getAllForMe();
getAllForMe();
getAllForMe();
getAllForMe();
getAllForMe();
System.out.println("!!!!!!!" + total);
avg = total/5;
System.out.println("~~~avg. Lag: " + avg);
response.processFinish(avg);
return avg;
}
public interface AsyncResponse{
void processFinish(double offSet);
}
public AsyncResponse response = null;
public offSetAsyncTask(AsyncResponse res, String name, Context c){
response = res;
serverName = name;
context = c;
}
private void getAllForMe(){
try{
DatagramSocket socket = new DatagramSocket();
InetAddress address = InetAddress.getByName(serverName);
byte[] buf = new NtpMessage().toByteArray();
DatagramPacket packet =
new DatagramPacket(buf, buf.length, address, 123);
// Set the transmit timestamp *just* before sending the packet
// ToDo: Does this actually improve performance or not?
NtpMessage.encodeTimestamp(packet.getData(), 40,
(System.currentTimeMillis()/1000.0) + 2208988800.0);
socket.send(packet);
// Get response
System.out.println("NTP request sent, waiting for response...\n");
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// Immediately record the incoming timestamp
destinationTimestamp =
(System.currentTimeMillis()/1000.0) + 2208988800.0;
// Process response
NtpMessage msg = new NtpMessage(packet.getData());
// Corrected, according to RFC2030 errata
roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
(msg.transmitTimestamp-msg.receiveTimestamp);
localClockOffset =
((msg.receiveTimestamp - msg.originateTimestamp) +
(msg.transmitTimestamp - destinationTimestamp)) / 2;
total+=localClockOffset;
// Display response
System.out.println("NTP server: " + serverName);
System.out.println(msg.toString());
System.out.println("Dest. timestamp: " +
NtpMessage.timestampToString(destinationTimestamp));
System.out.println("Round-trip delay: " +
new DecimalFormat("0.00").format(roundTripDelay*1000) + " ms");
System.out.println("Local clock offset: " +
new DecimalFormat("0.00").format(localClockOffset*1000) + " ms");
socket.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
那我怎么能同步兩部Android手機的時鍾呢? 我該如何解決這個問題?
從概念上講,您可以跳過同步系統時鍾,並確定相對偏移和漂移。 在“ Tiny-Sync:無線傳感器網絡的緊密時間同步”一文中 ,作者首先描述了節點i的時間
t i (t)= a i t + b i
在UTC T要約。
其中a i和b i是節點i時鍾的漂移和偏移。
由此,您可以根據節點2的時間t 2表示節點1的時間t 1 ,如
t 1 (t)= a 12 t 2 (t)+ b 12 。
為了估計這些系數,發送消息,如下所示:
每個郵件發件人都添加一個時間戳。 利用少至兩個數據點,可以估計兩個節點的偏移和漂移,使用基於樹的方法來同步節點網絡。
截至論文,
算法提供了非常好的精度( 如果仔細精心制作,則為微秒 ),並且在使用非常有限的資源的同時限制精度,[強調我的]
如果它是可以接受的,我認為我們應該切換視角 - 而不是相互同步設備A == B
(並且必須手動考慮偏移和延遲),我們可以讓每個設備與外部源(服務器)同步因為如果A == C
且B == C
則A == B
您的用例將類似於:
如果您只需要在一分鍾內獲得准確性,則公共API已經存在。 否則,服務器將是您自己創建的私有端點。
注意:由於您似乎的目標是同步播放,並且不同的設備具有不同的性能,因此您需要在播放開始前完全准備(加載/緩沖)媒體播放器。 可能會在收到歌曲之前立即同步時間
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.