androidkotlinbroadcastreceiveralarmmanager

Adroid Kotlin BroadcastReciver is called twice


I implemented an BroadcastReceiver. The Problem is, that it is allways called twice if it is triggered. I don't get why. I hope you can help me.

The manifest is the only place i register the receiver. I habe not registered it again in code.

the Alarm is scheduled in the onCreate Methode of MainActivity

enter image description here

AndroidManifest.xml:

<receiver android:name=".alarmManager.domain.AlarmReceiver"/>

MainActivity onCreate():

setContent {
    WorkingTimeCalculatorTheme {
        WorkingTimeCalculator()

        //Day Reminder Alarm
        val scheduler = AndroidAlarmSchedulerImpl(LocalContext.current)

        val localTimeReminder = LocalTime.of(10, 30)
        val nowNanos = LocalTime.now().toNanoOfDay()
        val notificationNanos = localTimeReminder.toNanoOfDay()
        val localDateReminder =
            LocalDate.now().plusDays(if (notificationNanos <= nowNanos) 1 else 0)

        val alarmItem: AlarmItem = AlarmItem(
            time = LocalDateTime.now()
                .plusSeconds(5),//LocalDateTime.of(localDateReminder, localTimeReminder),
            title = stringResource(R.string.EnterWorkingHours),
            message = stringResource(R.string.PleaseSetTheTimesForThisDay),
            notificationType = NotificationType.DayUnchangedReminder.value
        )
        alarmItem.let(scheduler::schedule)
    }
}

AlarmScheduleImpl:

class AndroidAlarmSchedulerImpl(
    private val context: Context
) : AlarmScheduler {

    private val alarmManager = context.getSystemService(AlarmManager::class.java)

    override fun schedule(item: AlarmItem) {
        val intent = Intent(context, AlarmReceiver::class.java).apply {
            putExtra("EXTRA_TITLE", item.title)
            putExtra("EXTRA_MESSAGE", item.message)
            putExtra("EXTRA_NOTIFICATION_TYPE", item.notificationType)
        }
        alarmManager.setRepeating(
            AlarmManager.RTC_WAKEUP,
            item.time.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000,
            60000, //AlarmManager.INTERVAL_DAY,
            PendingIntent.getBroadcast(
                context,
                item.hashCode(),
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

        )
    }

    override fun cancel(item: AlarmItem) {
        alarmManager.cancel(
            PendingIntent.getBroadcast(
                context,
                item.hashCode(),
                Intent(context, AlarmReceiver::class.java),
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
        )
    }
}

AlarmReceiver:

@AndroidEntryPoint
class AlarmReceiver : BroadcastReceiver() {

    @Inject
    lateinit var addDayReminderNotificationSingleton: AddDayReminderNotification

    override fun onReceive(context: Context?, intent: Intent?) {
        var title = intent?.getStringExtra("EXTRA_TITLE") ?: return
        title += "\n${LocalDate.now().toDateString()}"
        val message = intent.getStringExtra("EXTRA_MESSAGE") ?: return
        val notificationType =
            NotificationType.fromValue(intent.getIntExtra("EXTRA_NOTIFICATION_TYPE", 0))?.value

        Log.d("AlarmTest", "BroadCastReceiver Called")

        val notification = Notification(
            id = null,
            date = LocalDate.now(),
            time = LocalTime.now(),
            title = title,
            description = message,
            unread = true,
            notificationType = notificationType ?: 0
        )
        if (::addDayReminderNotificationSingleton.isInitialized) {
            CoroutineScope(Dispatchers.IO).launch {
                addDayReminderNotificationSingleton.addNotification(context, notification)
            }
        } else {
            Log.e("AlarmReceiver", "addDayReminderNotificationSingleton is not initialized")
        }


    }
}

Solution

  • You are scheduling an alarm every time WorkingTimeCalculatorTheme() recomposes. Either:

    The first option is vastly superior for something like an AlarmManager alarm.