You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Joda DateTime修改Android系统时间无效:无报错但时间未变更

问题分析与解决方案

嘿,我看了你的代码和问题描述,核心问题其实很明显:你的代码根本没有执行修改系统时间的操作,另外权限和工具库的用途也有需要注意的点,下面给你一步步拆解:

一、先搞清楚一个关键:Joda DateTime不能直接改系统时间

Joda DateTime只是个日期时间处理工具库,它的作用是帮你计算、格式化时间——比如你代码里的now.plusHours(12)只是算出了一个新的时间对象,但这个对象完全是内存里的,和系统时间没有任何关联,你得主动把这个计算出来的时间同步到系统里才行。

二、修改系统时间的必要前提(已root模拟器场景)

1. 必须声明权限

先在AndroidManifest.xml里加上修改时间的权限,就算是root设备,这些权限也是必填的:

<uses-permission android:name="android.permission.SET_TIME" />
<uses-permission android:name="android.permission.SET_TIME_ZONE" />

2. 两种可行的修改方式

因为你的模拟器已经root,这里给你两种靠谱的实现方式:

方式一:用root权限执行shell命令(最直接)

通过su获取root权限后,执行系统的date命令来修改时间,这是root设备上最稳定的方式:

private void settime1(){
    DateTime now = DateTime.now();
    DateTime targetTime = now.plusHours(12);
    // 把Joda时间转成Unix时间戳(秒级,shell的date命令支持这种格式)
    long timestamp = targetTime.getMillis() / 1000;

    try {
        // 启动root shell进程
        Process process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        // 执行修改时间的命令
        os.writeBytes("date -s @" + timestamp + "\n");
        // 退出shell
        os.writeBytes("exit\n");
        os.flush();
        // 等待命令执行完成
        process.waitFor();

        // 验证修改结果
        DateTime newNow = DateTime.now();
        Toast.makeText(MainActivity.this, "修改后时间:" + newNow.toString(), Toast.LENGTH_LONG).show();
    } catch (IOException | InterruptedException e) {
        e.printStackTrace();
        Toast.makeText(MainActivity.this, "修改失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
    }
}

方式二:调用Android系统API(需要root授权)

Android提供了AlarmManager.setTime()方法来修改系统时间,但这个方法只有系统应用或者获得root权限的应用才能调用:

private void settime1(){
    DateTime now = DateTime.now();
    DateTime targetTime = now.plusHours(12);
    long targetMillis = targetTime.getMillis();

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    if (alarmManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 6.0及以上需要先检查权限
            if (checkSelfPermission(Manifest.permission.SET_TIME) == PackageManager.PERMISSION_GRANTED) {
                alarmManager.setTime(targetMillis);
            } else {
                Toast.makeText(MainActivity.this, "缺少SET_TIME权限", Toast.LENGTH_LONG).show();
                return;
            }
        } else {
            // 低版本直接调用
            alarmManager.setTime(targetMillis);
        }

        // 验证修改结果
        DateTime newNow = DateTime.now();
        Toast.makeText(MainActivity.this, "修改后时间:" + newNow.toString(), Toast.LENGTH_LONG).show();
    }
}

三、额外注意点

  • 确认你的模拟器确实已经开启root模式:有些模拟器需要手动在设置里打开root权限(比如Genymotion的ADB设置、夜神模拟器的权限管理)。
  • 测试时可以先单独在模拟器的shell里执行su和date -s @<时间戳>命令,确认root环境正常。
  • 别再混淆Joda DateTime的作用啦,它只负责处理时间数据,修改系统时间必须靠Android的系统能力。

内容的提问来源于stack exchange,提问作者BBMM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:47:35