android - 警报重新安排 - 强制终止后,AlarmManager pendingIntent 不为空
问题描述
我正在寻找一种方法来了解应用程序何时以某种方式被强制终止,以便下次用户手动打开应用程序时我可以执行一些任务(重新启动警报、重新安排工作、进行清洁等)。为了实现这一点,我在很远的将来安排了一个 AlarmManager,每次应用程序启动时,我都会检查相应的待处理意图是否存在。如果它存在,则没有发生强制杀戮,所以我什么也不做。如果挂起的意图是空的,这意味着应用程序被强制终止并且警报被取消安排,所以我再次安排它并执行所有需要的任务。不幸的是,这种方法不起作用:如果我从设备设置中强制终止应用程序,那么当我第一次重新打开应用程序时,挂起的意图仍然存在(下面的方法 isForceStopped() 返回 false),
这是我发现的行为:
AlarmManager 在应用程序第一次启动时安排
我在设备设置中强制终止应用程序 我再次启动应用程序 -> 待处理的意图不为空(isForceStopped() 返回 false)
我关闭应用程序并重新启动它 -> 待定意图现在为空(isForceStopped() 返回 true,警报已重新安排
从现在开始,警报被安排并且待处理的意图不为空
鉴于这种行为,用户必须打开应用程序两次,然后我才能在强制终止后执行所需的操作。我的问题是:
为什么第一次启动应用程序时仍然存在待处理的意图?我的代码中是否缺少某些内容?
更一般地说,有没有更好的方法来实现我所需要的(了解发生了强制杀戮)?
当前代码
public class AlarmChecher {
private static final String ACTION_FORCE_STOP = "ACTION_FORCE_STOP";
private Context mContext;
private static final int ALARM_ID = -1;
private static final long TEN_YEARS = TimeUnit.DAYS.toMillis(10 * 365);
public AlarmChecher(Context context) {
mContext = context;
}
public boolean isForceStopped() {
PendingIntent pendingIntent = getPendingIntent(mContext, FLAG_NO_CREATE);
if (pendingIntent == null) {
setAlarmChecher(mContext);
return true;
} else {
return false;
}
}
private Intent getIntent(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(context, ForceStopRunnable.BroadcastReceiver.class));
intent.setAction(ACTION_FORCE_STOP);
return intent;
}
private PendingIntent getPendingIntent(Context context, int flags) {
Intent intent = getIntent(context);
return PendingIntent.getBroadcast(context, ALARM_ID, intent, flags);
}
private void setAlarmChecher(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = getPendingIntent(context, FLAG_UPDATE_CURRENT);
long triggerAt = System.currentTimeMillis() + TEN_YEARS;
if (alarmManager != null) {
alarmManager.setExact(RTC_WAKEUP, triggerAt, pendingIntent);
}
}
}
然后在我活动的 onCreate() 方法中
AlarmChecher alarmChecher = new AlarmChecher(this);
if (alarmChecher.isForceStopped()) {
//do actions
alarmJobUtils.rescheduleAll();
}
解决方案
不要对 . 使用负值ALARM_ID
。有许多关于requestCode
.
推荐阅读
- linux - 如何使用 curl 将浮点值作为查询参数传递?
- java - 检查一个java条件是否是另一个条件的子集
- c# - 模拟参数化异步方法
- oracle - 使 SQL*Plus 脚本退出
- php - pg_query_params 不替换查询中的参数
- android - 在flutter中发布apk android在启动时崩溃
- python - 对数正态分布
- c# - 尽管(通常)需要虚拟化,我如何在 winforms 应用程序中获得非虚拟化 DPI
- node.js - connectTimeout 在 mqtt node.js 中不起作用
- c# - 使用 JavaScriptSerializer 自定义 Date 对象的序列化