设置ROOTED手机的系统时间

时间:2012-01-05 07:33:26

标签: android

我目前正在尝试在软件中设置Android系统时间。是的,我知道有很多人尝试过 - 而且像我现在一样失败了。 : - )

但我也知道可以在ROOTED手机上设置Android系统时间。我已经测试了一个名为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 个答案:

答案 0 :(得分:53)

更新:此方法不再适用于最近的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]
  // 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);

首先,我是ClockSync的开发人员,我知道在Android上设置时间。

我担心Violet Giraffe提供的答案不正确。问题是普通用户应用程序无法访问 SET_TIME 权限。此权限只能由作为ROM的一部分安装的系统应用程序使用,或者使用与ROM本身相同的密钥签名(取决于供应商)。使用此方法的应用程序之一是NTPc。它使用AOSP密钥签名,可以安装在基于AOSP的Android ROM上,例如CyanogenMod。请注意,谷歌最近已禁止市场上出现AOSP密钥,而作者将永远无法更新其申请。 NTPc不能安装在大多数手机上使用的普通ROM上。

如果您需要详细信息,请务必阅读着名的问题4581 Allow user apps to set the system time的评论。请注意,Google的问题是拒绝,并带有以下注释:

  

嗨,应用程序无法改变时间。那里   安全的许多微妙方面可以依赖于当前时间,   例如证书到期,许可证管理等。我们没有   希望允许第三方应用程序在全球范围内破坏系统   就这样。


如何在有根设备上设置时间:

ClockSync设置时间的做法是更改/dev/alarm设备的权限。实质上,它在根shell中运行chmod 666 /dev/alarm。一旦此设备对所有用户具有写入权限,SystemClock. setCurrentTimeMillis(...)呼叫将成功。一些应用程序使用另一种方法,它们在root shell中使用适当的参数运行date命令,但是它容易出错且不太准确,因为超级用户shell和命令执行可能需要几秒钟。这种应用的一个例子是Sytrant

默认情况下,只有/dev/alarm尚未写入时,ClockSync才会设置666权限。这节省了CPU /电池,因为su / Superuser.apk执行相对昂贵。如果您担心安全性,则会有恢复权限选项,该选项会在设置时间后使警报设备获得权限。

为了更容易从应用程序访问root shell,我正在使用自己的帮助程序类: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。您可以使用Apache commons-net库中的NTP客户端从NTP服务器获取时间。

答案 1 :(得分:9)

您可以在root设备上设置系统日期和时间,如下所示

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