如果强制关闭目标应用程序,PendingIntent会怎样?

时间:2019-02-22 07:02:17

标签: android android-intent alarmmanager android-pendingintent

我实际上正在开发一个应在未来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)
    }

3 个答案:

答案 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被取消。