使用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
相关产品推荐
相关产品推荐

