拥有Android内核全权限:AlarmManager改时间致Fragment销毁的替代方案问询
替代的Android系统时间修改方案(内核全权限场景)
针对你的场景,这里提供两种无需依赖AlarmManager的系统时间修改方案,能避免原方法导致的Fragment意外销毁问题,且保证时间立即生效:
1. Shell命令直接修改
利用内核权限执行系统date命令直接修改时间,同步硬件时钟后发送广播通知系统:
private fun setTimeViaShell(hourOfDay: Int, minute: Int) { val c = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, hourOfDay) set(Calendar.MINUTE, minute) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } val timestamp = c.timeInMillis.coerceAtLeast(1194220800000L) val seconds = timestamp / 1000 try { // 修改系统时间 Runtime.getRuntime().exec(arrayOf("su", "-c", "date -s @$seconds")) // 同步到硬件RTC,避免重启后时间还原 Runtime.getRuntime().exec(arrayOf("su", "-c", "hwclock -w")) // 通知系统所有组件时间已变更 requireContext().sendBroadcast(Intent(Intent.ACTION_TIME_CHANGED)) } catch (e: IOException) { e.printStackTrace() } }
这种方式绕过了AlarmManager系统服务的中间逻辑,减少了系统触发组件生命周期变更的概率,同时date命令会立即生效。
2. JNI调用原生系统调用
通过JNI直接调用底层clock_settime系统函数,这是最底层的修改方式,效率最高:
首先编写JNI的C++代码:
#include <jni.h> #include <time.h> extern "C" JNIEXPORT void JNICALL Java_com_your_package_YourFragment_setSystemTimeNative(JNIEnv *env, jobject thiz, jlong timestamp) { struct timespec ts; ts.tv_sec = timestamp / 1000; // 转换毫秒为纳秒 ts.tv_nsec = (timestamp % 1000) * 1000000; // 修改系统实时时钟,需CAP_SYS_TIME权限(内核全权限已满足) clock_settime(CLOCK_REALTIME, &ts); }
然后在Kotlin中声明并调用:
// 声明JNI方法 external fun setSystemTimeNative(timestamp: Long) private fun setTimeViaJNI(hourOfDay: Int, minute: Int) { val c = Calendar.getInstance().apply { set(Calendar.HOUR_OF_DAY, hourOfDay) set(Calendar.MINUTE, minute) set(Calendar.SECOND, 0) set(Calendar.MILLISECOND, 0) } val timestamp = c.timeInMillis.coerceAtLeast(1194220800000L) // 调用原生方法修改时间 setSystemTimeNative(timestamp) // 发送广播通知系统 requireContext().sendBroadcast(Intent(Intent.ACTION_TIME_CHANGED)) }
这种方式完全跳过Android框架层的服务调用,直接操作内核时钟,几乎不会触发框架层的组件重启逻辑,能彻底解决Fragment意外销毁的问题。
注意事项
- 无论哪种方案,都需要发送
ACTION_TIME_CHANGED广播,否则系统组件和其他应用无法立即感知时间变化; - 两种方案都依赖内核/root权限,你的场景已满足条件;
- 原方法中Fragment销毁的原因大概率是
AlarmManager.setTime触发了系统服务的内部通知逻辑,导致关联组件的生命周期重启,绕过该服务即可避免。
内容的提问来源于stack exchange,提问作者Pouria Hemi
相关产品推荐
相关产品推荐

