在Android

时间:2015-11-16 16:37:05

标签: android

我需要一些初始化代码才能在每次重启后尽快运行一次,然后在设备运行时再也不会再运行。

  • 存储指示代码已运行的SharedPreference不合适,因为它可以在重新启动后继续存在。
  • 依赖ACTION_SHUTDOWN清除SharedPreference值不够好,因为有时候不会发送(例如取消电池)。
  • 使用静态字段表示代码已运行不合适,因为如果我的应用程序被杀,它将被重置。
  • 在我的Application类中使用一些初始化代码是不合适的,因为如果我的应用程序被杀,它会再次运行。
  • 接收ACTION_BOOT_COMPLETED几乎已经足够好了,但这可以在我的应用响应的其他广播之前(例如ACTION_TIME_CHANGED),并且可以在我从启动器启动我的应用后触发。我需要这个一次性设置代码才能运行。
  • 我不能依赖System.currentTimeMillis来计算启动时间,因为时钟更改会改变启动时间。

一种选择是获取设备的上次启动时间并查看是否已更改(System.elapsedTime()不够好)。我尝试过执行who -blast reboot等命令,但两者都被拒绝。

另一种选择是将设置/首选项存储在某个地方,只有在设备重新启动时才会重置,但如果我的应用程序被杀死则不会重置。

是否有其他选择或实现上述方法之一?

4 个答案:

答案 0 :(得分:6)

所以你想在任何其他应用程序执行开始之前在系统启动时运行代码吗?

如果是,那么这个想法, 为ACTION_BOOT_COMPLETED创建一个接收器,并将优先级设置为999,这是最高的,因此当设备启动时,它将始终触发。

答案 1 :(得分:6)

我找到了一个似乎可靠且符合我要求的解决方案。我读取了文件/proc/sys/kernel/random/boot_id的内容,每次重启设备时都会重置唯一的引导标识符。

通过读取此文件并将该值与存储在SharedPreferences中的值进行比较,我可以可靠地确定自上次运行初始化代码后设备是否已重新启动,而不依赖于设备时钟。这适用于所有用户配置文件,因为它们都有自己的SharedPreferences。

这种方法的优点是,每当我收到任何广播和我的应用程序启动时,我都可以检查更改,因此无论先发生什么,即使ACTION_BOOT_COMPLETED广播被延迟或错过,我都可以进行初始化(常见)在慢速设备上。)

不幸的是,没有其他答案提供了一种可靠的方法来做到这一点,但是Hardik Chauhan的意图过滤优先级提示很有用,因为我很早就收到了ACTION_BOOT_COMPLETED。

答案 2 :(得分:3)

  1. 随时随地收看ACTION_BOOT_COMPLETED,以及其他广播。

  2. 我认为Android会在您的onCreate课程中实例化并致电Application,如果您在AndroidManifest.xml中指定了一个,请先致电任意你的接收器,所以通过在那里插入代码,你将覆盖所有情况。

  3. 或者,如果没有Application课程,请在每个BroadcastReceivers个人中添加以下代码。

  4. 使用它来检测这是否是一个独特的启动:

    public static boolean hasRunSinceBoot(Context context) {
        long bootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime();
        SharedPreferences prefs = context.getSharedPreferences("my_prefs_file", Context.MODE_PRIVATE);
        if (prefs.getLong("last_boot_time", 0) == bootTime) {
            return true;
        }
        prefs.edit().putLong("last_boot_time", bootTime).apply();
        return false;
    }
    

    然后运行类似:

    if (!hasRunSinceBoot(context)) {
        //do whatever you need to do
    }
    

答案 3 :(得分:2)

抓住ACTION_USER_INITIALIZE这将完成这项工作。

如果多个用户在运行时登录,请确保只捕获第一个用户。有一个workarround管理它应该很容易。

一个示例是您将进程启动的确认存储在SharedPreference中,并在系统关闭时强制删除它。

这可能不是最优雅的方式,但你会读到你的目的地。

检查说明!! http://developer.android.com/reference/android/content/Intent.html#ACTION_USER_INITIALIZE

  

[...](第三方应用程序不会看到这个因为a   新初始化的用户没有任何第三方应用程序   为它安装。)这是在启动用户的早期发送的   在ACTION_BOOT_COMPLETED之前启动主应用程序的时间   发送。[...]

不幸的是,这仅适用于系统应用;在安全系统上。 愿你能找到一个工作场所。

但这是你按时间顺序流程所需要的。

如果这确实不起作用。

ACTION_BOOT_COMPLETED进行质量检查,确保您真正抓住了一次。

我认为服务正在追赶ACTION_BOOT_COMPLETED并首次保存其到来。因此,每次ACTION_BOOT_COMPLETED再次被捕时,您只需检查它是否是第一次。

同样在这里,当你启动时,你也应该重置我们之前设置的标志。

如果这里提到的所有内容都不起作用。

抓取/proc/uptime 所以你可以这样处理它。无权限。