Установка системного времени ROOTED телефона - PullRequest
22 голосов
/ 05 января 2012

В настоящее время я пытаюсь установить системное время Android в программном обеспечении. Да, я знаю, что многие люди пробовали это - и потерпели неудачу, как и я сейчас. : -)

Но я также знаю, что можно установить системное время Android на ROOTED телефонах. Я тестировал приложение под названием ClockSync, которое действительно точно.

Итак, я хочу узнать, как установить системное время на ROOTED-устройствах. Пожалуйста, не говорите, что это невозможно. : -)

Я пытался установить следующие разрешения:

<uses-permission android:name="android.permission.SET_TIME_ZONE"/>
<uses-permission android:name="android.permission.SET_TIME"/>

А потом в моем коде:

AlarmManager a = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
long current_time_millies = System.currentTimeMillis();
try {
    a.setTime((long)current_time_millies+10000);
} catch (Exception e) {
// Why is this exception thrown?
}

Но я всегда получаю следующее исключение:

java.lang.SecurityException: setTime: ни у пользователя 10054, ни у текущего процесса нет android.permission.SET_TIME.

Я тестирую его на том же устройстве, где отлично работает ClockSync. Итак - что я делаю не так? Или лучше: вы можете предоставить проверенный код, который работает?

Ответы [ 2 ]

53 голосов
/ 06 января 2012

ОБНОВЛЕНИЕ : этот метод больше не работает с последними версиями Android. Единственный другой способ, который мне известен, - использовать команду date для установки времени. Обратите внимание, что формат команды может отличаться в зависимости от версии Android и установленных сторонних инструментов (версия BusyBox date не поддерживает часовые пояса).

  // Android 6 and later default date format is "MMDDhhmm[[CC]YY][.ss]", that's (2 digits each)
  // month, day, hour (0-23), and minute. Optionally century, year, and second.
private static final SimpleDateFormat setDateFormat = new SimpleDateFormat("MMddHHmmyyyy.ss", Locale.US);

  // Standard Android date format: yyyymmdd.[[[hh]mm]ss]
  // /4133197/ustanovit-datu-iz-obolochki-na-android
private static final SimpleDateFormat setDateFormat = new SimpleDateFormat("yyyyMMdd.HHmmss", Locale.US);

  // BusyBox date format:
  // [[[[[YY]YY]MM]DD]hh]mm[.ss]
  // but recent versions also accept MMDDhhmm[[YY]YY][.ss]
private static final SimpleDateFormat bbSetDateFormat = new SimpleDateFormat("yyyyMMddHHmm.ss", Locale.US);

Прежде всего, я разработчик ClockSync и кое-что знаю о настройке времени на Android.

Боюсь, ответ, предоставленный Фиолетовым Жирафом , неверен. Проблема в том, что обычное пользовательское приложение не может получить доступ к разрешению SET_TIME . Это разрешение может использоваться только системными приложениями, которые установлены как часть ПЗУ или подписаны тем же ключом, что и само ПЗУ (зависит от поставщика). Одним из приложений, использующих этот подход, является NTPc . Он подписан ключом AOSP и может быть установлен на ПЗУ Android на основе AOSP, например, CyanogenMod. Обратите внимание, что Google недавно запретил использование ключей AOSP в Маркете, и автор никогда не сможет обновить свое приложение. NTPc нельзя установить на обычные ПЗУ, используемые на большинстве телефонов.

Если вам нужны подробности, обязательно прочитайте комментарии к известной проблеме 4581 : Разрешить приложениям пользователя устанавливать системное время . Обратите внимание, что проблема была отклонена Google со следующим комментарием:

Привет, это дизайн, который приложения не могут изменить время. Там Есть много тонких аспектов безопасности, которые могут полагаться на текущее время, такие как истечение срока действия сертификата, управление лицензиями и т. д. Мы не делаем хотите разрешить сторонним приложениям глобально нарушать работу системы таким образом.


Как установить время на рутированном устройстве:

То, что ClockSync делает для установки времени, меняет разрешение устройства /dev/alarm. По сути, он запускается chmod 666 /dev/alarm в корневой оболочке. Как только это устройство получит права на запись для всех пользователей, вызов SystemClock. setCurrentTimeMillis (...) будет успешным. Некоторые приложения используют другой подход, они запускают команду date в корневой оболочке с соответствующими аргументами, однако это подвержено ошибкам и является менее точным, поскольку выполнение оболочки и команды суперпользователя может занять несколько секунд. Примером такого приложения является Sytrant .

По умолчанию ClockSync устанавливает разрешение 666, только если /dev/alarm еще не доступно для записи. Это экономит процессор / батарею, потому что выполнение su / Superuser.apk относительно дорого. Если вы беспокоитесь о безопасности, есть опция Restore Permission , которая сделает разрешение для устройства тревоги 664 по истечении установленного времени.

Для более легкого доступа к корневой оболочке из приложения я использую свой собственный вспомогательный класс: ShellInterface . Другой вариант - использовать библиотеку RootTools .

Вот пример кода, основанного на ShellInterface класс:

  public void setTime(long time) {
    if (ShellInterface.isSuAvailable()) {
      ShellInterface.runCommand("chmod 666 /dev/alarm");
      SystemClock.setCurrentTimeMillis(time);
      ShellInterface.runCommand("chmod 664 /dev/alarm");
    }
  }

Не стесняйтесь проверять другие проблемы Android, связанные с настройкой времени:


Если вам нужно точное время в приложении без использования root и изменения системного времени, вы можете иметь свои собственные таймеры, например, основанные на Joda Time . Вы можете получить время с NTP-серверов с помощью NTP-клиента из библиотеки Apache commons-net .

9 голосов
/ 17 июня 2012

Вы можете установить системную дату и время на рутированном устройстве, как это

public void setDate()
    {
        try {
            Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
            os.writeBytes("date -s 20120419.024012; \n");
        } catch (Exception e) {
            Log.d(TAG,"error=="+e.toString());
            e.printStackTrace();
        }
    } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...