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

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

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

一种选择是获取设备的最后一次启动时间,看看它是否已经改变( System.elapsedTime()不够好)。 我已经尝试执行诸如who -blast reboot类的命令但是两者都拒绝了权限。

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

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

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

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

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

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

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

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

  1. 在你正在做的时候听取ACTION_BOOT_COMPLETED以及其他广播。

  2. 我相信Android会实例化并调用你的Application类的onCreate ,如果你在调用任何接收器之前在AndroidManifest.xml中指定了一个,那么通过在那里插入代码,你将涵盖所有情况。

  3. 或者,如果没有Application类,请将下面的代码粘贴到每个单独的BroadcastReceivers

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

 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 } 

赶上ACTION_USER_INITIALIZE这将完成这项工作。

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

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

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

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

[…](第三方应用程序不会看到这一点,因为新初始化的用户没有为其安装任何第三方应用程序。)这是在启动用户的早期发送的,大约是在家庭应用程序启动时,在发送ACTION_BOOT_COMPLETED之前。[…]

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

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

如果这真的不起作用。

ACTION_BOOT_COMPLETED进行质量检查,确实只是一次抓住它。

我认为服务捕获ACTION_BOOT_COMPLETED并首次保存它的到来。 因此,每次再次捕获ACTION_BOOT_COMPLETED时,您只需检查它是否是第一次。

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

如果真的在这里提到的一切都行不通。

获取/proc/uptime以便您可以这样处理它。 无需权限。