¿Cómo configurar la hora y la fecha del sistema móvil en Android?

Cuando desee cambiar la fecha o hora del sistema móvil en su aplicación, ¿cómo lo hace?

No puede hacerlo en un teléfono normal, ya que no es posible obtener el permiso SET_TIME. Este permiso tiene el nivel de protección de signatureOrSystem , por lo que no hay forma de que una aplicación de mercado cambie la hora global del sistema (pero tal vez con la magia del vodoo negro aún no lo sé).

No puede usar otros enfoques porque esto se evita en un nivel de Linux (consulte la respuesta larga a continuación): esta es la razón por la que fallarán todas las pruebas que usan terminales y SysExecs.

Si PUEDE obtener el permiso ya sea porque rooteó su teléfono o creó y firmó su propia imagen de plataforma, siga leyendo.

Respuesta corta

Es posible y se ha hecho. Necesitas android.permission.SET_TIME . Luego use el AlarmManager través de Context.getSystemService(Context.ALARM_SERVICE) y su método setTime() .

Fragmento para configurar el horario para 2010/1/1 12:00:00 de una actividad o servicio:

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

Si cambia la zona horaria, el enfoque debería ser muy similar (consulte android.permission.SET_TIME_ZONE y setTimeZone )

Respuesta larga

Como se ha señalado en varios subprocesos, solo el usuario del system puede cambiar la hora del sistema. Esto es solo la mitad de la historia. SystemClock.setCurrentTimeMillis() escribe directamente en /dev/alarm que es un archivo de dispositivo propiedad de un system que no tiene derechos de escritura del mundo. En otras palabras, solo los procesos que se ejecutan como system pueden usar el enfoque de SystemClock . Por esta razón, los permisos de Android no importan, no hay ninguna entidad involucrada que verifique los permisos adecuados.

Esta es la forma en que funciona la aplicación de configuración interna preinstalada. Simplemente se ejecuta bajo la cuenta de usuario del system .

Para todos los otros niños de la ciudad, está el administrador de alarmas. Es un servicio del sistema que se ejecuta en el proceso system_server bajo la cuenta de usuario del system adivina qué. Expone el método setTime mencionado pero impone el permiso SET_TIME y, a su vez, simplemente llama a SystemClock.setCurrentTimeMillis internamente (lo cual sucede porque el usuario está ejecutando el administrador de alarmas).

~~~ ¡Saludos!

De acuerdo con este hilo , las aplicaciones de los usuarios no pueden configurar el tiempo, independientemente de los permisos que le demos. En cambio, el mejor enfoque es hacer que el usuario configure la hora manualmente . Usaremos:

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

Desafortunadamente, no hay forma de vincularlos directamente a la configuración de tiempo (lo que les ahorraría un clic más). Al hacer uso de lapsedRealtime , podemos asegurarnos de que el usuario configure la hora correctamente.

Una solución para dispositivos rooteados podría ser ejecutar los comandos

  • su
  • date -s YYYYMMDD.HHMMSS

Cambiar fecha en cmd

Puedes hacer esto por código con el siguiente método:

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

Simplemente llame al método anterior de esta manera:

 changeSystemTime("2015","04","06","13","09","30"); 

No vi este en la lista en ninguna parte pero funciona para mí. Mi dispositivo está rooteado y tengo un superusuario instalado, pero si el superusuario funciona en dispositivos no rooteados, esto podría funcionar. Usé una AsyncTask y llamé a lo siguiente:

 protected String doInBackground(String... params){ Runtime.getRuntime().exec("su && date -s " + params[0]);} 

En nuestro caso de solicitud, la sucia solución fue:

Cuando el usuario está conectado a Internet, obtenemos la Hora de Internet (servidor NTP) y comparamos la diferencia (-) de la hora interna del dispositivo (registederOffsetFromInternetTime). Lo guardamos en el archivo de registro de configuración del usuario.

Utilizamos el tiempo de devide + registederOffsetFromInternetTime para considerar el tiempo correcto de actualización para NUESTRA aplicación.

Todos los procesos de GETHOUR verifican la diferencia entre la hora real y la hora de la última comparación (con la hora de Internet). Si el tiempo supera los 10 minutos, haga una nueva comparación para actualizar registederOffsetFromInternetTime y mantener la precisión.

Si el usuario usa la aplicación sin Internet, solo podemos usar el registederOffsetFromInternetTime almacenado como referencia y usarlo. Solo si el usuario cambia la hora en el dispositivo local cuando está desconectado y usa la aplicación, la aplicación considerará momentos incorrectos. Pero cuando el usuario regresa al acceso a Internet le advertimos sobre el cambio del reloj, pidiendo que se vuelva a sincronizar todo o que las actualizaciones se desconsuyan con la hora incorrecta.

gracias penquin. En quickshortcutmaker aprecio el nombre de la actividad de fecha / hora exactamente. para comenzar la configuración del tiempo del sistema:

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

`