Java 检查是否已在Android上启动BOOT_COMPLETED
我有一个处理多个事件的广播接收器。我需要它在引导时为我做一些特殊的事情,所以我注册了Java 检查是否已在Android上启动BOOT_COMPLETED,java,android,android-intent,Java,Android,Android Intent,我有一个处理多个事件的广播接收器。我需要它在引导时为我做一些特殊的事情,所以我注册了android.intent.action.boot\u,完成了intent,效果很好。如果设备已插入并正在为android.intent.action.action\u电源连接充电intent在BOOT\u完成之前启动,并且在开始工作之前工作。(我使用BOOT\u COMPLETED作为一种初始值设定项) 有没有办法检查BOOT\u COMPLETED事件是否已触发,以便在触发过早的情况下运行我的初始化代码?启
android.intent.action.boot\u,完成了intent,效果很好。如果设备已插入并正在为android.intent.action.action\u电源连接充电
intent在BOOT\u完成之前启动
,并且在开始工作之前工作。(我使用BOOT\u COMPLETED
作为一种初始值设定项)
有没有办法检查BOOT\u COMPLETED
事件是否已触发,以便在触发过早的情况下运行我的初始化代码?启动BOOT\u COMPLETED
时,您需要在共享引用中设置一个标记为“true”
因此,如果您的操作\u电源\u连接
在引导\u完成之前被触发
,那么您需要从SharedReferences检查标志的值
如果该值仍然为false,则表示BOOT_COMPLETED广播尚未启动,您不应执行操作
注意-还记得每次在SharedReferences中重置标志。我找到了另一个一致的解决方案。(我不能使用其他方法,因为我不是决定方法的人。)
使用这篇文章的答案:我可以将上次启动时间保存在SharedReferences(或其他存储)中。一旦启动时间与上次不同,我知道这是一个新的启动,可以应用我的初始化等
这是我最后编写的代码:
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;
}
private boolean checkIfRebooted(上下文){
SharedReferences prefs=context.getSharedReferences(“package.name.class”,context.MODE\u PRIVATE);
long savedUptime=prefs.getLong(“时间戳”,0);
long currentUptime=System.currentTimeMillis()-SystemClock.elapsedRealtime();
//给它一个10ms的阈值,因为计算有时可能会被关闭一次。
if(Math.abs(currentUptime-savedUptime)<10)
返回false;
prefs.edit().putLong(“时间戳”,currentUptime).apply();
返回true;
}
您可以使用/proc/sys/kernel/random/boot\u id中的内核引导id。
当代码接收到BOOT_COMPLETED时,将BOOT_id存储在共享首选项中。之后就简单了。如果/proc的boot_id等于共享首选项,则已处理boot_COMPLETED。否则,现在还没有。启动BOOT_COMPLETE时可以设置一个布尔值吗?不,没有办法。重构代码,使其更灵活。当你接收到第一次广播时,而不是当你接收到一个特定的广播时,初始化内容。考虑更改您的体系结构,可能使用一个组件,如服务
,以正确的顺序强制初始化。@SteveSmith当应用程序完全关闭/强制关闭时,该布尔值将被取消设置,如果我再次启动应用程序,该布尔值将无效。@XaverKapeller谢谢,这样做的实际目的是在设备重新启动后,在某些特殊情况下让用户注销。但由于应用程序运行非常重要,因此它会监听多个事件并检查它是否处于活动状态。电源事件将启动服务并登录设备,用户将能够听到来自登录的音频,这是不希望的,因为他不应该登录。但你可能是对的,因为我用错误的方式处理这个问题。你为什么不单独跟踪这两个问题呢?在处理操作\u电源\u连接之前,使用一些标志跟踪引导是否实际完成?或者让它们都触发相同的代码,但如果其中一个代码已经在运行,则忽略它,因为它已经处于处理状态。SharedReferences会保留重新启动。我如何知道何时重置该标志?您可以使用操作关闭广播或用户启动您的应用程序来重置该标志。两者都是重新设置标志的好人选。如果这个答案对你有帮助,请考虑接受和支持它。我不能依赖ActoNoSwitter,因为如果整个Android系统崩溃或发生意想不到的事情,我无法处理这个意图。尽管如此,我还是对这一努力表示赞赏。非常感谢。正如我所说,你也可以在应用程序启动时重置标志,使其更加可靠。不能说我同意这种方法,因为如果用户强制关闭,标志的状态肯定会出错。当OP的主要评论中有上述更合适的方法时,这似乎比任何事情都更具黑客性。你的答案是否准确描述了@Aritra Roy?@azizbekian给出的答案?否,因为他的方法基于收到的事件带有真/假标志。我可以安全地确定这是否是一个新的启动,并没有意外事件,这可能会出错。