如何在单Activity应用中解决点击通知后重复弹出通知的问题
问题原因
点击通知重复弹通知是两个逻辑共同导致的:
- 你给通知的
PendingIntent设置了Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK标记,每次点击通知都会销毁已存在的MainActivity,触发重建走onCreate生命周期 - 你在
onCreate中注册了viewModel.getReminderDate的观察者,Activity重建时观察者会重新回调,日期匹配就会再次调用notif()方法弹出通知
解决方法(无需新增Activity,维持单Activity架构)
1. 修改PendingIntent启动标记,复用MainActivity实例
替换原来的PendingIntent配置,不要销毁重建Activity,直接复用已有的实例:
val intent = Intent(this, MainActivity::class.java) .putExtra("toNotifFragment", "NotifFragment") .apply { // 替换原有的NEW_TASK和CLEAR_TASK标记 flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP } // 适配Android 12+对PendingIntent的flag要求 val pendingIntent : PendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PendingIntent.getActivity(this,0, intent, PendingIntent.FLAG_IMMUTABLE) } else { PendingIntent.getActivity(this,0, intent, 0) }
2. 新增onNewIntent方法处理通知跳转
复用MainActivity实例时不会触发onCreate,而是走onNewIntent生命周期,需要把跳转逻辑也放到这个方法里:
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) intent?.getStringExtra("toNotifFragment")?.let { if (it == "NotifFragment"){ findNavController(R.id.navHostFragment).navigate(R.id.transactionNotificationFragment) } } }
3. 增加通知防抖逻辑,避免同天重复弹出
你目前的逻辑只要日期匹配就会弹通知,建议加个本地标记,同一天内最多弹一次通知:
fun notif(){ // 先校验当天是否已经弹出过通知 val notifSp = getSharedPreferences("notification_config", Context.MODE_PRIVATE) val todayStr = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date()) if (notifSp.getString("last_notify_date", "") == todayStr) { return } // 原有创建通知、弹出通知的逻辑不变... // 弹出成功后记录当前日期 notifSp.edit().putString("last_notify_date", todayStr).apply() }
额外优化建议
你当前的观察者循环逻辑存在问题,遍历list的时候每次都取list.get(0)的值,如果你需要校验所有提醒日期,建议改成取list[i]。
内容的提问来源于stack exchange,提问作者Jugs
相关产品推荐
相关产品推荐

