【问题标题】:Programmatically set System Time以编程方式设置系统时间
【发布时间】:2018-05-06 08:38:18
【问题描述】:

我意识到这个问题出现在 SO 的其他地方,但是我已经尝试了所有可以在网站上找到的解决方案,但仍然遇到困难。这些问题(和他们的答案)也有好几年的历史了,与其评论老问题,我想我会在这里为其他人整合信息,并调查从那时到现在对 Android 的潜在相关变化。不过,如果您觉得这个问题属于重复问题,请将其标记为重复问题。

编辑:正如我所说,关于 SO 的其他答案并没有解决问题。我看不出用“不适合我”来评论每一个潜在的修复是多么有益帮助自己和他人解决问题,但如果是这样,那就这样吧。作为参考,有 3 个人将这些问题标记为可能与 this question 重复,因此我将那些无效的答案添加到下面的列表中。

我的应用程序有一些非常具体的需求,但为了简洁起见,我们假设我需要手动将系统时间和日期设置为固定值。下面我详细说明了我在尝试使其工作方面取得的进展。

该应用的最低 SDK 版本为 24,目标为 24。其他人发现他们需要将版本提高到此级别。

设备已root,应用程序正在安装到/system/app,以便我可以更改日期/时间。

有些人评论说应用程序完全不可能设置时间,但是看看 ClockSync 等应用程序,情况似乎并非如此。我知道我的应用将无法在 Play 商店中使用。

应用程序必须在没有用户输入的情况下自动设置日期/时间,因此使用以下代码进行用户设置将无济于事;

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

失败时我在敬酒中收到的错误是:

java.lang.securityexception: setTime: neither user 10051 nor current process has android.permission.SET_TIME

我已经尝试了上述编辑中引用的问题中的两种解决方案,这两种解决方案都涉及运行代码来设置日期:

Runtime.getRuntime().exec("su && date -s 20171122.153720");}

这两个答案都无济于事 - 时间不会改变,也不会引发异常。另一个答案需要互联网访问,这超出了我的问题范围。

考虑到以上所有因素,我在完成这项工作时是否遗漏了任何关键步骤,或者代码中是否有任何表明存在问题的内容?

【问题讨论】:

  • 我倾向于同意这不是重复的 - 我看到的其他答案似乎建议添加 SET_TIME 权限,我看到你已经尝试过了。我投票决定重新开放。
  • 谢谢,如果在 SO 中有更好的方法来处理这种情况,那么我会很感激有人真正解释如何这样做,而不是仅仅标记它并继续前进。我无法准确评论所有现有答案的详细程度 - 事实上,以我的代表级别,我还不能评论句号。
  • 看起来问题现在(在我看来是正确的)重新打开了。
  • 嗨!你找到解决办法了吗?

标签: java android date time programmatically


【解决方案1】:

事实证明,答案确实在于引用的问题found here。但是,对于 Android 7(可能还有 6 个,我尚未测试)设备,该命令是不同的。我没有在那里发表评论的声誉,所以如果有人想在该问题上粘贴/引用此答案,请继续。

我使用的日期代码格式为 MMddhhmmyy,而不是 yyyyMMdd.hhmmss;这适用于我在 Android 7 上。我还删除了附加的“-s”。我用来设置系统时间的完整工作代码如下。再次需要注意的是,这需要对设备进行生根,因此仅在像我这样的某些情况下有用。

     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。

【讨论】:

  • 4017是类型错误吗?
【解决方案2】:

如果您也需要设置第二个,请使用以下格式: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();

【讨论】:

    猜你喜欢
    • 2011-03-26
    • 1970-01-01
    • 2011-03-15
    • 2012-10-19
    • 2010-10-07
    • 2012-11-17
    • 1970-01-01
    • 2011-07-30
    • 2016-08-24
    相关资源
    最近更新 更多