在Android上每次启动后运行一次代码

在Android上每次启动后运行一次代码,android,Android,我需要一些初始化代码,以便在每次重新启动后尽快运行一次,然后在设备运行时不再运行 存储指示代码已运行的SharedReference是不合适的,因为它在重新启动后仍然有效 依靠ACTION\u SHUTDOWN清除SharedReference值不够好,因为有时无法发送该值(例如,电池已卸下) 使用静态字段指示代码已运行是不合适的,因为如果我的应用程序被终止,它将被重置 在我的应用程序类中使用一些初始化代码是不合适的,因为如果我的应用程序被终止,它将再次运行 接收动作\u启动\u完成几乎已经足

我需要一些初始化代码,以便在每次重新启动后尽快运行一次,然后在设备运行时不再运行

  • 存储指示代码已运行的SharedReference是不合适的,因为它在重新启动后仍然有效
  • 依靠
    ACTION\u SHUTDOWN
    清除SharedReference值不够好,因为有时无法发送该值(例如,电池已卸下)
  • 使用静态字段指示代码已运行是不合适的,因为如果我的应用程序被终止,它将被重置
  • 在我的应用程序类中使用一些初始化代码是不合适的,因为如果我的应用程序被终止,它将再次运行
  • 接收<代码>动作\u启动\u完成几乎已经足够了,但这可以在我的应用程序响应的其他广播之前进行(例如<代码>动作\u时间\u更改),并且可以在我已经从启动器启动我的应用程序后触发。在此之前,我需要运行此一次性安装代码
  • 我不能依靠
    System.currentTimeMillis
    来计算启动时间,因为时钟的变化会改变明显的启动时间
一个选项是获取设备的最后一次引导时间,并查看是否已更改(
System.elapsedTime()
不够好)。我尝试过执行像
who-b
last reboot
这样的命令,但这两个命令的权限都被拒绝

另一种选择是将设置/首选项存储在某个位置,只有在设备重新启动时,设置/首选项才会重置,但在我的应用程序被终止时,设置/首选项不会重置

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

  • 收听您正在进行的
    ACTION\u BOOT\u COMPLETED
    ,以及其他广播

  • 我相信Android会实例化并调用
    onCreate
    你的
    应用程序
    类,如果你在AndroidManifest.xml中指定了一个,然后再调用你的接收者的任何,因此通过将代码粘贴在那里,你将涵盖所有情况

  • 或者,如果没有
    应用程序
    类,请将下面的代码粘贴到每个
    广播接收器

  • 使用此选项可检测这是否是唯一引导:

    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
    }
    

    捕捉
    操作\u用户\u初始化
    这将完成任务

    如果多个用户在运行时登录,请确保只捕获第一个用户。让一个工作人员来管理它应该是一件容易的事

    例如,您将流程开始的确认信息存储在SharedReference中,并在系统关闭时强制删除它

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

    检查描述!!

    […](第三方应用程序不会看到这一点,因为 新初始化的用户没有任何第三方应用程序 这是在启动用户的早期,在 启动家庭应用程序的时间,在操作\u启动\u完成之前 已发送。[…]

    不幸的是,这只适用于系统应用程序;关于安全系统。 愿你能在附近找到工作

    但这正是你在时间顺序中需要的

    如果这真的不起作用

    ACTION\u BOOT\u COMPLETED
    执行一次质量检查,确保您一次就抓住了它

    我认为服务捕获了
    操作\u BOOT\u完成了
    并首次保存了它的到达。因此,每次
    操作\u BOOT\u COMPLETED
    再次被捕获时,您只需检查是否是第一次

    这里也是一样,当启动时,您还应该重置我们刚才设置的标志

    如果这里提到的一切都不起作用

    获取
    /proc/uptime

    所以你可以这样处理。不需要权限。

    那么您想在任何其他应用程序执行开始之前在系统启动时运行代码,对吗

    如果是的话,我的想法是,
    为“启动”完成的操作创建一个接收器,并将优先级设置为最高的999,以便在设备启动时始终首先触发该命令。

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

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

    这种方法的优点是,每当我收到任何广播,当我的应用程序启动时,我都可以检查是否有更改,这样我就可以运行初始化,不管首先发生什么,即使操作启动完成的广播延迟或错过(在慢速设备上很常见)


    不幸的是,其他答案都没有提供可靠的方法来实现这一点,但Hardik Chauhan的意向过滤器优先级提示很有用,因为我收到的动作启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动启动。如果您的应用程序在此之前接收到任何其他广播,例如
    操作时间\u更改
    ,则在接收到
    操作启动\u完成
    广播后,您可以将必要的任务排队,以便在需要执行的初始化之后运行。谢谢Mike,但不幸的是,第一次运行代码很重要,这通常是在发送操作\u BOOT\u COMPLETED之前。@DaveMorrissey您可以在应用程序接收到的第一次广播上运行初始化,而不管该操作是什么,但在这里您仍然存在确定最后一次启动的问题。然而,在启动初期