Android Kotlin中BroadcastReceiver被重复调用两次的问题求助
BroadcastReceiver触发时被调用两次的排查与解决
我实现了一个BroadcastReceiver,但触发时总会被调用两次,不清楚原因。我仅在AndroidManifest.xml中注册了该接收器,没有在代码中重复注册。闹钟是在MainActivity的onCreate方法中调度的,相关代码如下:
AndroidManifest.xml
<receiver android:name=".alarmManager.domain.AlarmReceiver"/>
MainActivity onCreate()代码
setContent { WorkingTimeCalculatorTheme { WorkingTimeCalculator() //每日提醒闹钟 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) } }
AndroidAlarmSchedulerImpl代码
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") } } }
可能的原因及解决方法
Activity重复触发onCreate:如果Activity因屏幕旋转、系统回收重建等原因多次执行onCreate,会重复调度闹钟。解决方式:
- 调度前先取消同类型闹钟,确保仅保留一个有效实例:
scheduler.cancel(alarmItem) scheduler.schedule(alarmItem) - 将调度逻辑移到
onStart并添加判断,仅在首次启动时执行。
- 调度前先取消同类型闹钟,确保仅保留一个有效实例:
PendingIntent的requestCode冲突:
item.hashCode()可能存在重复值,导致创建多个PendingIntent。可以改用固定唯一ID(如针对每日提醒用1001),或者重写AlarmItem的hashCode方法保证唯一性。AlarmManager重复触发:部分Android版本中
setRepeating可能因系统优化出现重复广播。可以改用setExactAndAllowWhileIdle,每次触发后手动设置下一次闹钟,替代重复调度。接收器实例重复创建:通过
@AndroidEntryPoint注入的接收器可能被系统创建多个实例。可以在onReceive中打印实例hashCode确认:Log.d("AlarmTest", "BroadCastReceiver Called, instance: ${this.hashCode()}")
内容的提问来源于stack exchange,提问作者SkAppCoding
相关产品推荐
相关产品推荐

