Configurar la hora del sistema del teléfono ROOTED

Actualmente estoy tratando de configurar el tiempo del sistema Android en el software. Sí, sé que mucha gente lo intentó, y falló como lo hago ahora. 🙂

Pero también sé que es posible establecer la hora del sistema Android en teléfonos ROOTED. He probado una aplicación llamada ClockSync que sí lo hace.

Entonces, lo que quiero es averiguar cómo configurar la hora del sistema en dispositivos ROOTED. Por favor no digas que no es posible. 🙂

Lo que intenté hasta ahora es establecer los siguientes permisos:

  

Y luego en mi código:

 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? } 

Pero siempre recibo la siguiente excepción:

java.lang.SecurityException: setTime: Ni el usuario 10054 ni el proceso actual tienen android.permission.SET_TIME.

Lo estoy probando en el mismo dispositivo donde ClockSync funciona perfectamente. Entonces, ¿qué estoy haciendo mal? O mejor: ¿Puedes proporcionar un código probado que funcione?

ACTUALIZACIÓN : este método ya no funciona con las versiones recientes de Android. La única otra forma que conozco es utilizar el comando de date para establecer la hora. Tenga en cuenta que el formato de comando puede ser diferente dependiendo de la versión de Android y de las herramientas de terceros instaladas (la versión de date de BusyBox no admite zonas horarias).

  // 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] // http://stackoverflow.com/questions/5300999/set-the-date-from-a-shell-on-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); 

En primer lugar, soy el desarrollador de ClockSync y sé algo sobre cómo configurar el tiempo en Android.

Me temo que la respuesta proporcionada por Violeta Jirafa no es correcta. El problema es que la aplicación de usuario normal no puede obtener acceso al permiso SET_TIME . Este permiso solo puede ser utilizado por aplicaciones del sistema que están instaladas como parte de la ROM o están firmadas con la misma clave que la propia ROM (depende del proveedor). Una de las aplicaciones que está utilizando este enfoque es NTPc . Está firmado con la clave AOSP y se puede instalar en las ROM de Android basadas en AOSP, como CyanogenMod. Tenga en cuenta que Google ha prohibido las claves AOSP de Market recientemente y que el autor nunca podrá actualizar su aplicación. NTPc no se puede instalar en las ROM comunes que se usan en la mayoría de los teléfonos.

Si necesita los detalles, asegúrese de leer los comentarios del famoso número 4581 : Permitir que las aplicaciones de los usuarios configuren la hora del sistema . Tenga en cuenta que el problema fue rechazado por Google con el siguiente comentario:

Hola, es por diseño que las aplicaciones no pueden cambiar el tiempo. Hay muchos aspectos sutiles de la seguridad que pueden depender de la hora actual, como la caducidad del certificado, la administración de licencias, etc. No queremos permitir que las aplicaciones de terceros interrumpan el sistema de esta manera.


Cómo establecer la hora en un dispositivo rooteado:

Lo que ClockSync hace para establecer el tiempo es cambiar el permiso del dispositivo /dev/alarm . Esencialmente, ejecuta chmod 666 /dev/alarm en el shell raíz. Una vez que este dispositivo tenga permisos de escritura para todos los usuarios, SystemClock. La llamada setCurrentTimeMillis (…) tendrá éxito. Algunas aplicaciones utilizan otro enfoque, ejecutan el comando de date en el shell raíz con los argumentos apropiados, sin embargo, es propenso a errores y es menos preciso porque el shell del superusuario y la ejecución del comando pueden tardar varios segundos. Un ejemplo de tal aplicación es Sytrant .

De forma predeterminada, ClockSync establece el permiso 666 solo si /dev/alarm no se puede escribir. Esto ahorra CPU / batería porque la ejecución de su / Superuser.apk es relativamente costosa. Si le preocupa la seguridad, existe la opción de restauración de permisos que hará que el dispositivo de alarma pase a 664 después del tiempo de configuración.

Para facilitar el acceso al shell de la raíz desde la aplicación, estoy usando mi propia clase de ayuda: ShellInterface . Otra opción es usar la biblioteca RootTools .

Aquí está el código de ejemplo basado en la clase ShellInterface :

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

No dude en consultar otros problemas de Android relacionados con el tiempo de configuración:

  • Problema 12497: capacidad para que las aplicaciones obtengan permiso para establecer el tiempo
  • Problema 18681: Implementar Timesync por NTP
  • Problema 67: configuración automática de fecha y hora usando SIM o NTP

Si necesita un tiempo preciso en la aplicación sin usar la raíz y cambiar la hora del sistema, puede tener sus propios temporizadores, por ejemplo, basados ​​en Joda Time . Puede obtener el tiempo de los servidores NTP que utilizan el cliente NTP de la biblioteca Apache commons-net .

puede configurar la fecha y la hora del sistema en un dispositivo rooteado como este

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