How to set mobile system time and date in android?
You cannot on a normal off the shelf handset, because it's not possible to gain the SET_TIME permission. This permission has the protectionLevel of signatureOrSystem
, so there's no way for a market app to change global system time (but perhaps with black vodoo magic I do not know yet).
You cannot use other approaches because this is prevented on a Linux level, (see the long answer below) - this is why all trials using terminals and SysExecs gonna fail.
If you CAN gain the permission either because you rooted your phone or built and signed your own platform image, read on.
Short Answer
It's possible and has been done. You need android.permission.SET_TIME
. Afterward use the AlarmManager
via Context.getSystemService(Context.ALARM_SERVICE)
and its method setTime()
.
Snippet for setting the time to 2010/1/1 12:00:00 from an Activity or Service:
Calendar c = Calendar.getInstance();
c.set(2010, 1, 1, 12, 00, 00);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setTime(c.getTimeInMillis());
If you which to change the timezone, the approach should be very similar (see android.permission.SET_TIME_ZONE
and setTimeZone
)
Long Answer
As it has been pointed out in several threads, only the system
user can change the system time. This is only half of the story. SystemClock.setCurrentTimeMillis()
directly writes to /dev/alarm
which is a device file owned by system
lacking world writeable rights. So in other words only processes running as system
may use the SystemClock
approach. For this way android permissions do not matter, there's no entity involved which checks proper permissions.
This is the way the internal preinstalled Settings App works. It just runs under the system
user account.
For all the other kids in town there's the alarm manager. It's a system service running in the system_server
process under the - guess what - system
user account. It exposes the mentioned setTime
method but enforces the SET_TIME
permission and in in turn just calls SystemClock.setCurrentTimeMillis
internally (which succeeds because of the user the alarm manager is running as).
Cheers
According to this thread, user apps cannot set the time, regardless of the permissions we give it. Instead, the best approach is to make the user set the time manually. We will use:
startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));
Unfortunately, there is no way to link them directly to the time setting (which would save them one more click). By making use of ellapsedRealtime, we can ensure that the user sets the time correctly.
A solution for rooted devices could be execute the commands
- su
- date -s YYYYMMDD.HHMMSS
You can do this by code with the following method:
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();
}
}
Just call the previous method like this:
changeSystemTime("2015","04","06","13","09","30");