Как я могу получить «сетевое» время (из настройки «Автоматически» под названием «Использовать сетевые значения»), а НЕ время на телефоне? - PullRequest
54 голосов
/ 08 ноября 2011

Я бы хотел, чтобы в моем приложении был найден способ синхронизации даты и времени с чем-то, заданным внешним источником.

Я не хочу использовать телефонное время, потому что я могу получить разницу в 5 минут в реальном времени. и 5 минут больше или меньше = 10 минут!

Я слышал информацию о времени на спутниках GPS или в сетевых антеннах.

Я пытался использовать System.getCurrentTime, но я получаю текущее состояние устройства, поэтому, если мое устройство настроено на 5 минут раньше, оно отображает неправильное время.

EDIT

Чтобы задать короткий вопрос: как я могу получить это время?

enter image description here

Ответы [ 7 ]

55 голосов
/ 21 ноября 2011

Я не знал, но нашел вопрос интересным.Так что я копался в коде Android ... Спасибо open-source:)

Экран, который вы показываете, DateTimeSettings.Флажок «Использовать сетевые значения» связан с общим предпочтением String KEY_AUTO_TIME = "auto_time";, а также с Settings.System.AUTO_TIME

. Эти настройки наблюдаются наблюдаемым вызываемым mAutoTimeObserver в сети 2 ServiceStateTracker с:GsmServiceStateTracker и CdmaServiceStateTracker.

Обе реализации вызывают метод, называемый revertToNitz(), когда настройки становятся истинными.Очевидно, NITZ является эквивалентом NTP в мире операторов.

Итог: вы можете установить время на значение, предоставленное оператором благодаря revertToNitz().К сожалению, я не нашел механизма для получения сетевого времени.Если вам действительно нужно это сделать, боюсь, вам придется скопировать эти реализации ServiceStateTracker s, поймать намерение, поднятое фреймворком (я полагаю), и добавить метод получения к mSavedTime.

22 голосов
/ 06 февраля 2013

Получить библиотеку из 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 () совпадает с System.currentTimeMillis ().

Следует использовать метод getReceiveTimeStamp () или getTransmitTimeStamp ().

Вы можете увидеть разницу после установки системного времени на 1 час назад.

local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()

NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()
7 голосов
/ 16 апреля 2015

Попробуйте этот фрагмент кода:

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());

Обязательно добавьте разрешение в Manifest

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
2 голосов
/ 25 мая 2012

Мне показалось, что это работает:

LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

Работа на Android 2.2 API (уровень 8)

1 голос
/ 29 июня 2017

NITZ является формой NTP и отправляется на мобильное устройство через уровни 3 или NAS. Обычно это сообщение рассматривается как информация GMM и содержит следующую информацию:

Некоторые операторы не поддерживают это, а некоторые поддерживают и неправильно его настраивают.

СИГНАЛЬНОЕ СООБЩЕНИЕ СЛОЯ 3

Время: 9: 38: 49.800

GMM ИНФОРМАЦИЯ 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

M Протокол Дискриминатор (шестнадцатеричные данные: 8)

(0x8) Mobility Management message for GPRS services

Индикатор пропуска M (шестнадцатеричные данные: 0) Значение: 0 M Тип сообщения (шестнадцатеричные данные: 21) Номер сообщения: 33

O Сетевой часовой пояс (шестнадцатеричные данные: 4680) Значение часового пояса: GMT + 2: 00 O Универсальное время и часовой пояс (шестнадцатеричные данные: 47716070 70831580) Год: 17 Месяц: 06 День: 07 Час: 07 Минута: 38 Второе: 51 Значение часового пояса: GMT + 2: 00 O Летнее время в сети (шестнадцатеричные данные: 490100) Значение летнего времени: без регулировки

Данные уровня 3: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00

0 голосов
/ 15 апреля 2018

Теперь вы можете получить время для текущего местоположения, но для этого вам нужно установить постоянный часовой пояс системы по умолчанию. setTimeZone(String timeZone), который можно получить из

Calendar calendar = Calendar.getInstance();
 long now = calendar.getTimeInMillis();
 TimeZone current = calendar.getTimeZone();

setAutoTimeEnabled(boolean enabled)

Устанавливает, будет ли время настенных часовдолжен синхронизироваться с автоматическим обновлением времени из 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);

Я искал ответ такого типа. Я прочитал ваш ответ, но не удовлетворился, и он немного устарел.Я нашел новое решение и поделился им.:)

Для получения дополнительной информации посетите: https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

0 голосов
/ 08 ноября 2011

сигнал времени не встроен в сетевые антенны: вам нужно использовать протокол NTP, чтобы получить время на сервере ntp. существует множество клиентов ntp, доступных как автономные исполняемые файлы или библиотеки.

сигнал GPS действительно включает в себя точный сигнал времени, который доступен для любого «исправления».

однако, если ни сеть, ни gps недоступны, ваш единственный выбор - прибегнуть к времени телефона ... вашим лучшим решением будет использование общесистемной настройки для автоматической синхронизации времени телефона с gps или ntp time, затем всегда используйте время телефона.

обратите внимание, что время телефона, если оно синхронизируется регулярно, не должно сильно отличаться от времени gps или ntp. Также обратите внимание, что принуждение пользователя к синхронизации его времени может быть навязчивым, вам лучше спросить своего пользователя, принимает ли он синхронизацию. наконец, вы уверены, что вам абсолютно необходимо точное время?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...