设置ROOTED手机的系统时间

use*_*536 22 android

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

但我也知道可以在ROOTED手机上设置Android系统时间.我已经测试了一个名为ClockSync的应用程序.

所以我想知道如何在ROOTED设备上设置系统时间.请不要说这是不可能的.:-)

到目前为止我尝试的是设置以下权限:

<uses-permission android:name="android.permission.SET_TIME_ZONE"/>
<uses-permission android:name="android.permission.SET_TIME"/>
Run Code Online (Sandbox Code Playgroud)

然后在我的代码中:

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?
}
Run Code Online (Sandbox Code Playgroud)

但我总是得到以下例外:

java.lang.SecurityException:setTime:用户10054和当前进程都没有android.permission.SET_TIME.

我在ClockSync完美运行的同一设备上进行测试.那么 - 我做错了什么?或者更好:你能提供有效的测试代码吗?

Cra*_*der 54

更新:此方法不再适用于最新的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);
Run Code Online (Sandbox Code Playgroud)

首先,我是ClockSync的开发者,我知道在Android上设置时间.

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

如果您需要详细信息,请务必阅读着名问题4581的注释:允许用户应用程序设置系统时间.请注意,该问题已被Google 拒绝,并带有以下评论:

嗨,按设计,应用程序无法改变时间.安全性有许多微妙的方面可以依赖于当前时间,例如证书过期,许可证管理等.我们不希望允许第三方应用程序以这种方式全局破坏系统.


如何在root设备上设置时间:

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

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

为了更容易从应用程序访问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");
    }
  }
Run Code Online (Sandbox Code Playgroud)

随意查看与设置时间相关的其他Android问题:


如果您在应用程序中需要精确的时间而不使用root并更改系统时间,则可以使用自己的计时器,例如基于Joda Time.您可以使用Apache commons-net库中的NTP客户端从NTP服务器获取时间.

  • 仅供参考,这种方法对我有用,直到新的Lollipop许可模式.我不能再以这种方式设置日期/时间了. (2认同)
  • 在Lollipop和Marshmallow上,我不得不切换到对"date"进行root调用,只有包含的用法不支持/不支持-s选项.所以我切换到"date mmddHHmmYYYY.ss".请注意,使用情况与其他人报告的内容不同. (2认同)

Kar*_*ran 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();
        }
    } 
Run Code Online (Sandbox Code Playgroud)