Search code examples
androidandroid-intentalarmmanagerandroid-pendingintent

What happens to a PendingIntent if the target app was force-closed?


I'm actually working on an app that should post a notification 5 days in the future.

Using AlarmManager, I send a PendingIntent to my Receiver class. Everything works fine until I force close my app. In this case, the notification doesn't appear.

So my question: What happens to this PendingIntent, which was fired and did not reach its target? When my app is finally restarted, can I check for PendingIntents, that did not reach its target?

EDIT 1:

These are the essential parts of my Broadcast Receiver:

    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)
    }

Solution

  • The answer is short: Active PendingIntents are cancelled on an application force-stop.