Intereting Posts
Обнаружение столкновений и реакция на столкновение Изменение позиции просмотра после окончания анимации Ошибка выполнения для задачи «app: mergeDebugResources» Crunching Cruncher … png failed Android: использование AUTO-CANCEL при уведомлении, когда ваше приложение работает в фоновом режиме Что делает synchronized () / wait () / notifyAll () в Java? Обновление Android Studio 2.2 Gradle Crash casting AndroidKeyStoreRSAPrivateKey для RSAPrivateKey Добавление точки останова в Eclipse приводит к сбою Dalvik Получить другого дочернего элемента, который разделяет родительский элемент с текущим представлением Лучше использовать адаптер курсора или адаптер Array Код кинжала, который дает NoClassDefFoundError при запуске Espresso Tests, нормально работает нормально работает От разработки веб-приложений до Android OnItemClickListener не запускает пользовательский ArrayAdapter Как установить фоновые рисунки программно в Android Получение фотографии из контакта

System.currentTimeMillis () возвращает неверную метку времени на Huawei

Проблема в том, что System.currentTimeMillis() возвращает неправильные миллисекунды с разными диапазонами времени, главным образом в будущем, иногда до 6 месяцев, но варьируется от нескольких секунд до нескольких месяцев.

Устройство, на котором это происходит, представляет собой планшетную модель Huawei M2-A201W на android 5.1.1, версия ядра: **3.10.74-gdbd9055**

Мое первое предположение заключалось в том, что NTP каким-то образом возился со временем, но у меня есть тысячи этих планшетов, а некоторые из них не имеют сетевого подключения, без SIM-карты, поэтому нет GSM / 3G / 4G.

Im с помощью System.currentTimeMillis() для сохранения в столбце таблицы, для которой была строка, созданная в локальной базе данных sqlite.

Это аномально происходит очень часто (30% каждого вызова System.currentTimeMillis() ) на планшетах, которые я использую.

Solutions Collecting From Web of "System.currentTimeMillis () возвращает неверную метку времени на Huawei"

Как обходной способ использования System.currentTimeMillis() , возможно, вы можете позволить обработчику sqlite создавать временную метку и посмотреть, разрешает ли эта проблема вашей проблеме?

Определите / измените свой «созданный» -колон с timestamp default current_timestamp или по default(strftime('%Y-%m-%d %H:%M:%f', 'now')) если вам нужны миллисекунды, как это:

sqlite> create table my_table(id integer primary key autoincrement not null, name text, created timestamp default(strftime('%Y-%m-%d %H:%M:%f', 'now')) not null);

sqlite> insert into my_table(name) values ('MyTestRow1');
sqlite> insert into my_table(name) values ('MyTestRow2');

sqlite> select * from my_table;

1|MyTestRow1|2017-08-07 10:08:50.898
2|MyTestRow2|2017-08-07 10:08:54.701

Java API вызывает System.currentTimeMillis() в платформе Android, используя POSIX api gettimeofday чтобы получить время в миллисекундах. См. Здесь .

 static jlong System_currentTimeMillis(JNIEnv*, jclass) { timeval now; gettimeofday(&now, NULL); jlong when = now.tv_sec * 1000LL + now.tv_usec / 1000; return when; } 

Предполагается, что каждый вызов gettimeofday будет успешным. Думаю, ваша проблема может произойти здесь.

Лучше проверить возвращаемое значение каждого вызова API и определить, что делать дальше, если произойдет ошибка.

Поэтому я предлагаю более надежный метод в JNI с вашей собственной реализацией, как показано ниже. Вызовите эти API POSIX по порядку, если gettimeofday не удалось, вызовите clock_gettime , если он снова не удался, time вызова.

 struct timeval now; if (gettimeofday(&now, NULL) != 0) { struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { now.tv_sec = ts.tv_sec; now.tv_usec = ts.tv_nsec / 1000LL; } else { now.tv_sec = time(NULL); now.tv_usec = 0; } } jlong when = now.tv_sec * 1000LL + now.tv_usec / 1000LL; __android_log_print(ANDROID_LOG_INFO, "TAG", "%lld", when); 

Как насчет получения временной метки из-за запуска команды «date +% s » в ядре Linux?

Здесь «+% s» – секунды с 1970-01-01 00:00:00 UTC. (Руководство GNU Coreutils 8.24)

  try { // Run the command Process process = Runtime.getRuntime().exec("date +%s"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); // Grab the results StringBuilder log = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { log.append(line); } } catch (IOException e) { e.printStackTrace(); } 

Если вы напечатаете это,

 Log.e("unix_time: ", "" + log.toString()); 

Вы получите временную метку Unix, например 1502187111

Чтобы преобразовать его обратно в объект даты, умножьте его на 1000, поскольку java ожидает миллисекунды,

 Date time = new Date(Long.parseLong(log.toString()) * 1000); Log.e("date_time: ", "" + time.toString()); 

Это даст вам простой формат даты. Например Вт Авг 08 16:15:58 GMT + 06: 00 2017

Когда у вас нет SIM-карты, поэтому нет GSM / 3G / 4G, ваш телефон не может обновить правильное время на основе предоставленного в сети времени / зоны.

Введите описание изображения здесь

Таким образом, устройства с сетью показывают правильное время, в то время как другие устройства без сети могут показывать неправильное время – вам нужно вручную установить правильное время. System.currentTimeMilis () считывает время из вашей системы. G Но при включении питания часы работают.

Проверьте, заблокирован ли NTP (UDP-порт 123) приложениями с помощью Socket или DatagramSocket. Примечание. NTP применяется к сценарию, в котором часы всех хостов или маршрутизаторов в сети должны быть одинаковыми. Если ваше устройство переключается на две (или более) разные сети и получает время, обновляемое из разных источников, оно может меняться во времени.

В конечном счете, ваше системное время меняется, поэтому оно колеблется. Если вы вручную установите System.currentTimeMilis () после того, как вы вручную отключите автоматическую дату и время, я считаю, что это не колеблется (нет аномалий). Если это так, ваш планшет Huewai не содержит ошибок.

Поскольку вы упомянули, что большинство звонков получают правильное время, и это происходит только в 30% случаев, я бы создал приемник для ACTION_TIME_CHANGED и ACTION_TIMEZONE_CHANGED трансляций, чтобы узнать, когда изменится время. Возможно, это даст вам понять, что меняет время.

Вместе с ConnectivityManager вы можете определить, подключено ли устройство и какой тип соединения у вас есть, возможно, какое-то соединение вызывает изменение времени.

 // init the register and register the intents, in onStart, using: receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { getNetworkInfo(); if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) Log.d(this.getClass().getName(), "Detected a time change. isWifiConn: " + isWifiConn + " isMobileConn: " + isMobileConn); if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) Log.d(this.getClass().getName(), "Detected a timezone change. isWifiConn: " + isWifiConn + " isMobileConn: " + isMobileConn); } }; IntentFilter filters = new IntentFilter(); filters.addAction(Intent.ACTION_TIME_CHANGED); filters.addAction(Intent.ACTION_TIMEZONE_CHANGED); registerReceiver(receiver, filters); Log.d(DEBUG_TAG, "Receiver registered"); // do not forget to unregister the receiver, eg. onStop, using: unregisterReceiver(receiver); //... private void getNetworkInfo() { ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); isWifiConn = networkInfo.isConnected(); networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); isMobileConn = networkInfo.isConnected(); Log.d(DEBUG_TAG, "Wifi connected: " + isWifiConn); Log.d(DEBUG_TAG, "Mobile connected: " + isMobileConn); } 

У этого устройства есть реальный аппаратный RTC? Я не мог найти окончательного ответа от поисковых систем и чтения спецификаций. Прогон:

 $ dmesg -s 65535 | grep -i rtc 

Из оболочки должен дать вам ответ. Вы должны увидеть что-то вроде этого (будет отличаться от набора микросхем и версии ядра):

 [ 3.816058] rtc_cmos 00:02: RTC can wake from S4 [ 3.816429] rtc_cmos 00:02: rtc core: registered rtc_cmos as rtc0 [ 3.816510] rtc_cmos 00:02: alarms up to one month, y3k, 242 bytes nvram, hpet irqs 

Если сообщение grep (и вы не указали на весь буфер сообщений ядра), то есть ответ. У вас нет часов, чтобы держать время на этих устройствах. Вы всегда будете нуждаться в NTP и рабочем сетевом подключении к Интернету, чтобы сохранить такое устройство без синхронизации часов в синхронизации с мировым временем.

RTC: https://en.wikipedia.org/wiki/Real-time_clock