以编程方式设置系统时间
Programmatically set System Time
我意识到这个问题出现在 SO 的其他地方,但是我已经尝试了我可以在网站上找到的所有解决方案,但仍然遇到困难。这些问题(及其答案)也有好几年了,与其评论旧问题,我想我应该在这里为其他人整合信息,并调查从那时到现在对 Android 的潜在相关更改。尽管如此,如果您认为此问题符合重复条件,请将其标记为重复。
编辑:正如我所说,关于 SO 的其他答案并没有解决问题。 我看不出如何用 "Doesn't work for me" 评论每一个潜在的修复有利于帮助自己和他人解决问题,但既然如此,那就这样吧。作为参考,3 人已将问题标记为 this question 的潜在重复项,因此我将这些无效答案添加到下面的列表中。
我的应用程序有一些非常具体的需求,但为了简洁起见,我们假设我需要手动将系统时间和日期设置为固定值。下面我详细介绍了一些关于我在尝试使这项工作取得进展的笔记。
该应用的最低 SDK 版本为 24,目标是 24。其他人发现他们需要将版本提高到这个级别。
设备已 root,正在将应用程序安装到 /system/app,以便我可以更改 date/time。
有人评论说,应用程序完全不可能设置时间,但是看看 ClockSync 等应用程序,情况似乎并非如此。我知道我的应用程序将无法在 Play 商店中使用。
应用程序必须在没有用户输入的情况下自动设置 date/time,因此使用以下代码让用户设置它无济于事;
startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));
我通过两种方式将设置时间权限添加到清单中,一种是单独添加,另一种是一起添加。我还尝试添加有关删除 maxSDKversion 的部分。
<uses-permission android:name="android.permission.SET_TIME" tools:remove="android:maxSdkVersion" />
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signature|system"/>
我读到某些权限不仅需要清单条目,还需要用户接受并允许它们。但是,SET_TIME 不在其中。无论如何我确实尝试过这样做,但是我的许可请求被自动拒绝而没有显示确认框,可能是因为它实际上并没有首先需要许可。
我用来尝试设置时间的代码如下:
try {
Calendar c = Calendar.getInstance();
c.set(2017, 11, 21, 12, 32, 30);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setTime(c.getTimeInMillis());
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
失败时我在 toast 中收到的错误是:
java.lang.securityexception: setTime: neither user 10051 nor current process has android.permission.SET_TIME
我已经尝试了上述编辑中引用的问题中的两种解决方案,这两种解决方案都涉及 运行 用于设置日期的代码:
Runtime.getRuntime().exec("su && date -s 20171122.153720");}
这两个答案什么都不做——时间没有改变,也没有抛出异常。另一个答案需要互联网访问,这超出了我的问题范围。
考虑到以上所有情况,我在完成这项工作时是否遗漏了任何关键步骤,或者代码中是否有任何表明存在问题的地方?
事实证明,答案 确实 就在所引用的问题 found here 中。但是,对于 Android 7 个(可能还有 6 个,我还没有测试过)设备,命令是不同的。我没有资格在那里发表评论,所以如果有人希望 paste/reference 这个问题的答案,请继续。
我使用的日期代码格式是 MMddhhmmyy,而不是 yyyyMMdd.hhmmss;这适用于 Android 7。我还删除了附加的“-s”。我用来设置系统时间的完整工作代码如下。再次需要注意的是,这需要对设备进行 root,因此仅在像我这样的某些情况下有用。
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String command = "date 1123104017\n";
// Log.e("command",command);
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (InterruptedException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
为清楚起见,我输入的日期是 2017 年 11 月 23 日 10:40 上午。
如果您也需要设置第二个,请使用此格式:MMddhhmmyy.ss
如果你有很长的时间价值,使用这个:
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddhhmmyy.ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeValue);
Date date = calendar.getTime();
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String command = "date " + dateFormat.format(date) + "\n";
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
我意识到这个问题出现在 SO 的其他地方,但是我已经尝试了我可以在网站上找到的所有解决方案,但仍然遇到困难。这些问题(及其答案)也有好几年了,与其评论旧问题,我想我应该在这里为其他人整合信息,并调查从那时到现在对 Android 的潜在相关更改。尽管如此,如果您认为此问题符合重复条件,请将其标记为重复。
编辑:正如我所说,关于 SO 的其他答案并没有解决问题。 我看不出如何用 "Doesn't work for me" 评论每一个潜在的修复有利于帮助自己和他人解决问题,但既然如此,那就这样吧。作为参考,3 人已将问题标记为 this question 的潜在重复项,因此我将这些无效答案添加到下面的列表中。
我的应用程序有一些非常具体的需求,但为了简洁起见,我们假设我需要手动将系统时间和日期设置为固定值。下面我详细介绍了一些关于我在尝试使这项工作取得进展的笔记。
该应用的最低 SDK 版本为 24,目标是 24。其他人发现他们需要将版本提高到这个级别。
设备已 root,正在将应用程序安装到 /system/app,以便我可以更改 date/time。
有人评论说,应用程序完全不可能设置时间,但是看看 ClockSync 等应用程序,情况似乎并非如此。我知道我的应用程序将无法在 Play 商店中使用。
应用程序必须在没有用户输入的情况下自动设置 date/time,因此使用以下代码让用户设置它无济于事;
startActivity(new Intent(android.provider.Settings.ACTION_DATE_SETTINGS));
我通过两种方式将设置时间权限添加到清单中,一种是单独添加,另一种是一起添加。我还尝试添加有关删除 maxSDKversion 的部分。
<uses-permission android:name="android.permission.SET_TIME" tools:remove="android:maxSdkVersion" />
<permission android:name="android.permission.SET_TIME"
android:protectionLevel="signature|system"/>
我读到某些权限不仅需要清单条目,还需要用户接受并允许它们。但是,SET_TIME 不在其中。无论如何我确实尝试过这样做,但是我的许可请求被自动拒绝而没有显示确认框,可能是因为它实际上并没有首先需要许可。
我用来尝试设置时间的代码如下:
try {
Calendar c = Calendar.getInstance();
c.set(2017, 11, 21, 12, 32, 30);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setTime(c.getTimeInMillis());
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
失败时我在 toast 中收到的错误是:
java.lang.securityexception: setTime: neither user 10051 nor current process has android.permission.SET_TIME
我已经尝试了上述编辑中引用的问题中的两种解决方案,这两种解决方案都涉及 运行 用于设置日期的代码:
Runtime.getRuntime().exec("su && date -s 20171122.153720");}
这两个答案什么都不做——时间没有改变,也没有抛出异常。另一个答案需要互联网访问,这超出了我的问题范围。
考虑到以上所有情况,我在完成这项工作时是否遗漏了任何关键步骤,或者代码中是否有任何表明存在问题的地方?
事实证明,答案 确实 就在所引用的问题 found here 中。但是,对于 Android 7 个(可能还有 6 个,我还没有测试过)设备,命令是不同的。我没有资格在那里发表评论,所以如果有人希望 paste/reference 这个问题的答案,请继续。
我使用的日期代码格式是 MMddhhmmyy,而不是 yyyyMMdd.hhmmss;这适用于 Android 7。我还删除了附加的“-s”。我用来设置系统时间的完整工作代码如下。再次需要注意的是,这需要对设备进行 root,因此仅在像我这样的某些情况下有用。
try {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String command = "date 1123104017\n";
// Log.e("command",command);
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (InterruptedException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
为清楚起见,我输入的日期是 2017 年 11 月 23 日 10:40 上午。
如果您也需要设置第二个,请使用此格式:MMddhhmmyy.ss
如果你有很长的时间价值,使用这个:
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddhhmmyy.ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeValue);
Date date = calendar.getTime();
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
String command = "date " + dateFormat.format(date) + "\n";
os.writeBytes(command);
os.flush();
os.writeBytes("exit\n");
os.flush();
process.waitFor();