我实际上正在开发一个应在未来5天发布通知的应用程序。
使用AlarmManager,我将PendingIntent发送到我的Receiver类。 一切正常,直到我强制关闭我的应用程序。在这种情况下,通知不会出现。
所以我的问题是: 被触发但未达到目标的PendingIntent会如何处理? 当我的应用程序最终重新启动时,我可以检查未达到其目标的PendingIntents吗?
编辑1:
这些是我的广播接收器的基本组成部分:
override fun onReceive(context: Context?, intent: Intent?) {
if (context != null && intent?.action != null) {
when (intent.action) {
INTENT_ACTION_BOOT_COMPLETED -> handleDeviceBoot()
INTENT_ACTION_REMINDER -> handleReminder(context, intent.getLongExtra(EXTRA_ITEM_ID, -1))
}
}
}
private suspend fun schedule(context: Context, itemId: Long, fireDate: LocalDateTime) = withContext(Dispatchers.IO) {
AlarmManagerCompat.setAndAllowWhileIdle(
getAlarmManager(context),
AlarmManager.RTC,
fireDate.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(),
makePendingIntent(context, itemId)
)
with(AppDatabase.get(context).reminderDao()) {
val oldReminder = getItemReminder(itemId)
if (oldReminder == null) {
insert(Reminder(itemId = itemId, fireDate = fireDate))
} else {
update(Reminder(id = oldReminder.id, itemId = itemId, fireDate = fireDate))
}
}
}
private suspend fun cancel(context: Context, itemId: Long) = withContext(Dispatchers.IO) {
val reminderDao = AppDatabase.get(context).reminderDao()
val reminder = reminderDao.getItemReminder(itemId)
reminder?.let {
getAlarmManager(context).cancel(makePendingIntent(context, itemId))
reminderDao.delete(it)
}
}
private fun getAlarmManager(context: Context) = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
private fun makePendingIntent(context: Context, itemId: Long): PendingIntent {
val alarmIntent = Intent(context, ReminderManager::class.java).apply {
action = INTENT_ACTION_REMINDER
putExtra(EXTRA_ITEM_ID, itemId)
}
return PendingIntent.getBroadcast(context, itemId.toInt(), alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
答案 0 :(得分:0)
如Official Android Documentation
中所定义PendingIntent本身只是对系统维护的令牌的引用,该令牌描述了用于检索令牌的原始数据。这意味着,即使其拥有的应用程序的进程被杀死,PendingIntent本身也将在已赋予它的其他进程中保持可用。如果创建的应用程序以后重新检索相同类型的PendingIntent(相同的操作,相同的Intent操作,数据,类别和组件以及相同的标志),则它将收到表示相同令牌的PendingIntent(如果该令牌仍然有效),并且可以因此调用cancel()将其删除。
重新访问您的代码以检查是否还有其他因素会导致此问题。
答案 1 :(得分:0)
当您“强制关闭”应用程序时,该应用程序将设置为“停止状态”。在“停止状态”下,除非用户手动重新启动应用程序,否则您的应用程序将不会由Android自动启动。这意味着,如果您“强制关闭”您的应用程序,您的应用程序将不会收到广播Intent
的广播,直到用户手动将其重新启动。
我希望(尽管我自己还没有尝试过),如果您安排在时间X发出警报,而在时间X之前“强制关闭”应用程序,则在时间X发生时,警报管理器将尝试发送PendingIntent
,但是Android将拒绝实际执行BroadcastReceiver
,因为该应用处于“停止状态”。在这种情况下,我预计触发器会丢失。 Android不会重试或重新安排它。
基本上,当用户“强制关闭”应用程序时,他是在告诉Android他不再希望该应用程序运行,包括该应用程序可能具有的任何后台进程或将来希望启动的进程。
答案 2 :(得分:0)
答案很简短:在应用程序强制停止时,活动的PendingIntent被取消。