Je voudrais dans mon application trouver un moyen de synchroniser la date et l'heure avec quelque chose donné par une source externe.
Je ne veux pas utiliser l'heure du téléphone parce que je pourrais avoir une différence d'environ 5 minutes par rapport au temps réel. et 5 minutes supplémentaires ou moins = 10 minutes!
J'ai entendu parler de l'heure dans les satellites GPS ou dans les antennes du réseau.
J'ai essayé avec System.getCurrentTime mais j'obtiens le courant du périphérique, donc, si mon périphérique est configuré 5 minutes plus tôt, il affiche l'heure incorrecte.
MODIFIER
Pour faire une petite question: comment puis-je obtenir ce temps?
Je ne savais pas, mais trouvais la question intéressante. J'ai donc creusé dans le code Android ... Merci open-source :)
L’écran que vous montrez est DateTimeSettings
. La case à cocher "Utiliser les valeurs fournies par le réseau" est associée à la préférence partagée String KEY_AUTO_TIME = "auto_time";
et également à Settings.System.AUTO_TIME
.
Cette configuration est observée par un observateur appelé mAutoTimeObserver
dans les 2 réseaux ServiceStateTracker
s: GsmServiceStateTracker
et CdmaServiceStateTracker
.
Les deux implémentations appellent une méthode appelée revertToNitz()
lorsque les paramètres deviennent vrais . Apparemment, NITZ est l’équivalent de NTP dans le monde du transporteur.
Conclusion: vous pouvez régler l’heure sur la valeur fournie par le transporteur grâce à revertToNitz()
. Malheureusement, je n’ai pas trouvé de mécanisme permettant d’obtenir l’heure du réseau. Je pense que si vous avez vraiment besoin de faire cela, vous devrez copier ces implémentations de ServiceStateTracker
s, attraper l'intention émise par le framework (je suppose) et ajouter un getter à mSavedTime
.
Obtenez la bibliothèque de http://commons.Apache.org/net/download_net.cgi
//NTP server list: http://tf.nist.gov/tf-cgi/servers.cgi
public static final String TIME_SERVER = "time-a.nist.gov";
public static long getCurrentNetworkTime() {
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
//long returnTime = timeInfo.getReturnTime(); //local device time
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime(); //server time
Date time = new Date(returnTime);
Log.d(TAG, "Time from " + TIME_SERVER + ": " + time);
return returnTime;
}
getReturnTime () est identique à System.currentTimeMillis ().
la méthode getReceiveTimeStamp () ou getTransmitTimeStamp () doit être utilisée.
Vous pouvez voir la différence après avoir réglé l'heure système il y a 1 heure.
local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()
NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()
Essayez cet extrait de code:
String timeSettings = Android.provider.Settings.System.getString(
this.getContentResolver(),
Android.provider.Settings.System.AUTO_TIME);
if (timeSettings.contentEquals("0")) {
Android.provider.Settings.System.putString(
this.getContentResolver(),
Android.provider.Settings.System.AUTO_TIME, "1");
}
Date now = new Date(System.currentTimeMillis());
Log.d("Date", now.toString());
Assurez-vous d'ajouter une permission dans Manifest
<uses-permission Android:name="Android.permission.WRITE_SETTINGS"/>
Cela a semblé fonctionner pour moi:
LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();
Travailler sur l'API Android 2.2 (niveau 8)
NITZ est une forme de NTP et est envoyé au périphérique mobile sur des couches de couche 3 ou NAS. Généralement, ce message est considéré comme une information GMM et contient les informations suivantes:
Certains opérateurs ne le supportent pas et certains le supportent et l’ont mal configuré.
MESSAGE DE SIGNALISATION DE LA COUCHE 3
Heure: 9: 38: 49.800
INFORMATIONS GMM 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)
Discriminateur de protocole M (données hexadécimales: 8)
(0x8) Mobility Management message for GPRS services
M Indicateur de saut (données hexadécimales: 0) Valeur: 0 M Type de message (données hexadécimales: 21) Numéro du message: 33
O Fuseau horaire du réseau (données hexadécimales: 4680) Valeur du fuseau horaire: GMT + 2: 00 O Heure et fuseau horaire universels (données hexadécimales: 47716070 70831580) Année: 17 Mois: 06 Jour: 07 Heure: 07 Minute: 38 Deuxième: 51 Valeur du fuseau horaire: GMT + 2: 00 O Heure d’hiver de l’été sur le réseau (données hexadécimales: 490100) Valeur de l'heure d'été: aucun ajustement
Données de couche 3: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00
Maintenant, vous pouvez obtenir l'heure pour l'emplacement actuel, mais pour cela, vous devez définir le fuseau horaire par défaut persistant du système .setTimeZone(String timeZone)
qui peut être obtenu à partir de
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
TimeZone current = calendar.getTimeZone();
setAutoTimeEnabled(boolean enabled)
Définit si l’horloge murale doit être synchronisée ou non avec les mises à jour automatiques de NTP.
TimeManager timeManager = TimeManager.getInstance();
// Use 24-hour time
timeManager.setTimeFormat(TimeManager.FORMAT_24);
// Set clock time to noon
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 12);
long timeStamp = calendar.getTimeInMillis();
timeManager.setTime(timeStamp);
Je cherchais ce type de réponse. J'ai lu votre réponse, mais je n’étais pas satisfaite et c’était un peu vieux. J'ai trouvé la nouvelle solution et la partage. :)
Pour plus d'informations, visitez le site: https://developer.Android.com/things/reference/com/google/Android/things/device/TimeManager.html