Как установить мобильное системное время и дату в Android? - PullRequest
40 голосов
/ 26 августа 2009

Если вы хотите изменить дату или время мобильной системы в своем приложении, как вы это делаете?

Ответы [ 6 ]

62 голосов
/ 29 июля 2012

Вы не можете получить обычную телефонную трубку с полки, потому что невозможно получить разрешение SET_TIME. Это разрешение имеет protectionLevel из signatureOrSystem, поэтому рыночное приложение не может изменить глобальное системное время (но, возможно, с помощью магии черного vodoo я пока не знаю).

Вы не можете использовать другие подходы, потому что это запрещено на уровне Linux (см. Длинный ответ ниже) - вот почему все испытания с использованием терминалов и SysExecs потерпят неудачу.

Если вы МОЖЕТЕ получить разрешение либо потому, что вы рутировали свой телефон, либо создали и подписали собственный образ платформы, читайте дальше.

Короткий ответ

Это возможно и было сделано. Вам нужно android.permission.SET_TIME. Затем используйте AlarmManager через Context.getSystemService(Context.ALARM_SERVICE) и метод s setTime().

Фрагмент для установки времени на 2010/1/1 12:00:00 из действия или службы:

Calendar c = Calendar.getInstance();
c.set(2010, 1, 1, 12, 00, 00);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setTime(c.getTimeInMillis());

Если вы хотите изменить часовой пояс, подход должен быть очень похожим (см. android.permission.SET_TIME_ZONE и setTimeZone)

Длинный ответ

Как было указано в нескольких потоках, только пользователь system может изменять системное время. Это только половина истории. SystemClock.setCurrentTimeMillis() напрямую записывает в /dev/alarm, который является файлом устройства, принадлежащим system, не имеющим мировых прав на запись. Другими словами, только процессы, работающие как system, могут использовать SystemClock подход. Для этого способа разрешения для Android не имеют значения, здесь не участвует ни один объект, который проверяет правильные разрешения.

Так работает внутреннее предустановленное приложение «Настройки». Он просто запускается под учетной записью system.

Для всех остальных детей в городе есть диспетчер сигнализации. Это системная служба, запущенная в процессе system_server под учетной записью пользователя - угадайте, что - system. Он предоставляет упомянутый метод setTime, но обеспечивает разрешение SET_TIME и, в свою очередь, просто вызывает SystemClock.setCurrentTimeMillis внутренне (что успешно из-за пользователя, от имени которого работает диспетчер аварий).

~~~ Приветствия

21 голосов
/ 13 мая 2010

Согласно этой теме , пользовательские приложения не могут устанавливать время независимо от того, какие разрешения мы ему предоставляем. Вместо этого лучше всего заставить пользователя установить время вручную . Мы будем использовать:

startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));

К сожалению, нет возможности напрямую связать их с настройкой времени (что могло бы спасти их еще одним кликом). Используя ellapsedRealtime , мы можем гарантировать, что пользователь правильно установит время.

12 голосов
/ 06 апреля 2015

Решением для корневых устройств может быть выполнение команд

  • су
  • дата -с ГГГГММДД.ЧЧММСС

Change date on cmd

Вы можете сделать это с помощью кода следующим способом:

private void changeSystemTime(String year,String month,String day,String hour,String minute,String second){
    try {
        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        String command = "date -s "+year+month+day+"."+hour+minute+second+"\n";
        Log.e("command",command);
        os.writeBytes(command);
        os.flush();
        os.writeBytes("exit\n");
        os.flush();
        process.waitFor();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Просто вызовите предыдущий метод следующим образом:

changeSystemTime("2015","04","06","13","09","30");
3 голосов
/ 20 мая 2015

Я нигде не видел этого в списке, но он работает для меня. Мое устройство имеет root-права, и у меня установлен суперпользователь, но если суперпользователь работает на некорневых устройствах, это может работать Я использовал AsyncTask и вызвал следующее:

protected String doInBackground(String... params){
Runtime.getRuntime().exec("su && date -s " + params[0]);}
1 голос
/ 20 июля 2016

В нашем случае применения грязный обходной путь был:

Когда пользователь подключен к Интернету, мы получаем Интернет-время (NTP-сервер) и сравниваем разницу (-) времени внутреннего устройства (registederOffsetFromInternetTime). Мы сохраняем его в файле конфигурации пользователя.

Мы используем время devide + registederOffsetFromInternetTime, чтобы определить правильное время обновления для НАШЕГО приложения.

Все процессы GETHOUR проверяют разницу между фактическим временем и временем последнего сравнения (со временем в Интернете). Если время превышает 10 минут, сделайте новое сравнение, чтобы обновить registederOffsetFromInternetTime и сохранить точность.

Если пользователь использует приложение без Интернета, мы можем использовать только registederOffsetFromInternetTime, хранящийся в качестве ссылки, и использовать его. Просто если пользователь изменит время на локальном устройстве в автономном режиме и использует приложение, приложение будет считать неправильное время. Но когда пользователь возвращается к доступу в Интернет, мы предупреждаем, что часы изменились, с просьбой повторно синхронизировать все или отменить обновления, сделанные в автономном режиме с неправильным часом.

0 голосов
/ 13 марта 2014

спасибо пенкин. В quickshortcutmaker я точно улавливаю название установки даты / времени. Итак, чтобы начать настройку системного времени:

Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings",
         "com.android.settings.DateTimeSettingsSetupWizard"));      
startActivity(intent);

`

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