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

拥有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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:45:24