【问题标题】:Check if BOOT_COMPLETED has been fired already on Android检查 BOOT_COMPLETED 是否已在 Android 上触发
【发布时间】:2017-02-27 15:59:40
【问题描述】:

我有一个可以处理多个事件的广播接收器。我需要它在启动时为我做一些特殊的事情,所以我注册了 android.intent.action.BOOT_COMPLETED 意图,它工作正常。如果设备已插入并正在充电,则 android.intent.action.ACTION_POWER_CONNECTED 意图在 BOOT_COMPLETED 之前触发,并且在它应该做的事情之前工作。 (我使用BOOT_COMPLETED 作为一种初始化程序)。

有没有办法检查BOOT_COMPLETED 事件是否已被触发,以便我可以在事件过早触发的情况下运行我的初始化代码?

【问题讨论】:

  • 你能在 BOOT_COMPLETE 被触发时设置一个布尔值吗?
  • 不,没有办法做到这一点。重构您的代码,使其更加灵活。当您收到第一个广播而不是收到特定广播时初始化内容。考虑改变你的架构,也许使用像Service 这样的组件来以正确的顺序强制初始化。
  • @SteveSmith 当应用程序完全关闭/强制关闭时布尔值将被取消设置,如果我再次启动应用程序将无效。
  • @XaverKapeller 谢谢,这样做的实际目的是在设备重新启动后在某些特殊情况下注销用户。但由于应用程序正在运行非常重要,它正在侦听多个事件并检查它是否处于活动状态。电源事件将启动服务并登录设备,用户将能够从登录中听到音频,这是不希望的,因为他不应该登录。但你可能是对的,我正在接近这个以错误的方式解决问题。
  • 你为什么不单独跟踪这两个?通过喜欢使用一些标志来跟踪 Boot 在处理 ACTION_POWER_CONNECTED 之前是否实际完成?或者让它们都触发相同的代码,但如果一个已经在运行,则忽略它,因为它已经处于处理状态。

标签: java android android-intent


【解决方案1】:

BOOT_COMPLETED 被触发时,您需要在SharedPreferences 中设置一个标志 为“true”。

所以,现在如果您的 ACTION_POWER_CONNECTEDBOOT_COMPLETED 之前被触发,那么您需要检查 SharedPreferences 中标志的值。

如果该值仍为 false,则表示 BOOT_COMPLETED 广播尚未触发,您不应执行操作。

注意 - 还要记住每次重置 SharedPreferences 中的标志

【讨论】:

  • SharedPreferences 持续重启。我怎么知道何时重置该标志?
  • 您可以使用 ACTION_SHUTDOWN 广播或如果用户启动您的应用程序来做到这一点。两者都是重置标志的好人选。如果此答案对您有帮助,请考虑接受并投票。
  • 我不能依赖 ACTION_SHUTDOWN 因为如果整个 android 系统崩溃或发生意外情况而我无法处理意图。不过,我很欣赏这种努力。谢谢!
  • 正如我所说,您还可以在启动应用程序时重置标志,使其在这种情况下更加可靠。
  • 不能说我同意这种方法,因为如果用户强制关闭,标志的状态肯定会出错。当在 OP 的主要 cmets 中有上面声明的更合适的方法时,这似乎比任何事情都更 hacky。
【解决方案2】:

我找到了另一个一致的解决方案。 (我不能使用另一种方法,因为我不是那个可悲地决定方法的人。)

使用这篇文章的答案:How to get Android system boot time 我可以将上次启动时间保存在 SharedPreferences(或其他一些存储)中。一旦启动时间与上次不同,我就知道它是新启动并且可以应用我的初始化等。

这是我最终编写的代码:

private boolean checkIfRebooted(Context context) {
    SharedPreferences prefs = context.getSharedPreferences("package.name.class", Context.MODE_PRIVATE);

    long savedUptime = prefs.getLong("timestamp", 0);
    long currentUptime = System.currentTimeMillis() - SystemClock.elapsedRealtime();

    // Giving it a threshold of 10ms since the calculation may be off by one sometimes.
    if (Math.abs(currentUptime - savedUptime) < 10)
        return false;

    prefs.edit().putLong("timestamp", currentUptime).apply();
    return true;
}

【讨论】:

  • 你的答案不是准确地描述了@Aritra Roy 给出的答案吗?
  • @azizbekian 不,因为他的方法是根据收到的事件使用真/假标志。我可以安全地确定它是否是新靴子,并且不会出现可能出错的意外事件。
【解决方案3】:

您可以使用 /proc/sys/kernel/random/boot_id 中的内核引导 ID。 当代码收到 BOOT_COMPLETED 时,将 boot_id 存储在共享首选项中。之后就很简单了。如果 /proc 中的 boot_id 等于共享首选项,则 BOOT_COMPLETED 已被处理。否则,还没有。

【讨论】:

    猜你喜欢
    • 2011-10-14
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多