Android Intent Extras值不随FCM新数据更新问题咨询
问题
我使用FCM向Android应用发送通知,通知由FirebaseMessagingService接收并处理,此部分功能正常。我从FCM通知中提取信息,传入FirebaseMessagingService内的函数生成Intent,在发送至MainActivity前,Intent及其Extras包含最新的FCM数据(此阶段一切正常),代码如下:
const val channelId = "notification_channel" const val channelName = "com.prod.myApp" fun generateNotification(goToFragment: String, contact_id: String, source_origin: String){ val intent = Intent(this, MainActivity::class.java) intent.putExtra("fragmentToLoad", goToFragment) intent.putExtra("contact_id", contact_id) intent.putExtra("source_origin", source_origin) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE) var builder: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, channelId) .setSmallIcon(R.drawable.ic_baseline_back_hand_24) .setAutoCancel(true) .setVibrate(longArrayOf(1000, 1000, 1000, 1000)) .setOnlyAlertOnce(true) .setContentIntent(pendingIntent) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationChannel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH) notificationManager.createNotificationChannel(notificationChannel) } notificationManager.notify(0, builder.build()) }
MainActivity接收Intent并按如下逻辑处理:
onNewIntent(intent) //NOTE: See below if (intent.extras != null) { if(intent.hasExtra("fragmentToLoad")){ when(intent.getStringExtra("fragmentToLoad").toString()){ "GetPic" -> { myViewModel.setContactsOrigin(intent.getStringExtra("source_origin").toString()) myViewModel.setPostcardContactID(intent!!.getStringExtra("contact_id").toString()) supportFragmentManager.findFragmentById(R.id.myNavHostFragment) as NavHostFragment val navController = navHostFragment.navController navController.navigate(R.id.GetPic) } else -> { Log.d("mainActivity","Intent option " + intent.hasExtra("fragmentToLoad").toString() + " is not an anticipated option") } } }
MainActivity中还单独实现了onNewIntent方法:
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) // Update the intent with new data }
问题在于MainActivity中getStringExtra("source_origin")的值始终不更新,一直是首次运行时的数值(尽管FirebaseMessagingService中该值已多次修改)。例如首次运行时source_origin为"banana",后续即使改为"orange",MainActivity中仍显示"banana"。打开指定Fragment的功能正常,所有操作在模拟器中进行,多次清理缓存及重启Android Studio均无效。请问该错误持续出现的原因是什么?
原因分析与解决方案
核心原因
问题出在PendingIntent的复用机制:
- 创建PendingIntent时使用了固定的
requestCode=0,且仅设置PendingIntent.FLAG_MUTABLE标记。 - 系统会缓存相同requestCode、相同组件的PendingIntent,当后续尝试创建新的PendingIntent时,会直接返回缓存的旧实例,不会更新Intent的Extras数据。
- 这就导致即使你生成了带新数据的Intent,MainActivity收到的仍是第一次缓存的Extras值。
直接修复方案
修改PendingIntent的创建逻辑,添加PendingIntent.FLAG_UPDATE_CURRENT标记,确保Intent内容变化时,系统更新已有的PendingIntent:
val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT )
额外优化点
- 修复MainActivity的Intent处理逻辑:
手动调用onNewIntent(intent)是错误的,onNewIntent是系统回调方法,无需手动触发。应将Intent处理逻辑抽成独立方法,在onCreate和onNewIntent中统一调用:override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 其他初始化代码 handleIntent(intent) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) handleIntent(intent) } private fun handleIntent(intent: Intent) { if (intent.extras != null && intent.hasExtra("fragmentToLoad")) { when(intent.getStringExtra("fragmentToLoad")) { "GetPic" -> { intent.getStringExtra("source_origin")?.let { myViewModel.setContactsOrigin(it) } intent.getStringExtra("contact_id")?.let { myViewModel.setPostcardContactID(it) } val navHostFragment = supportFragmentManager.findFragmentById(R.id.myNavHostFragment) as NavHostFragment val navController = navHostFragment.navController navController.navigate(R.id.GetPic) } else -> { Log.d("mainActivity","Intent option is not an anticipated option") } } } } - 避免通知覆盖:
当前使用notificationManager.notify(0, builder.build())的固定ID0,新通知会直接覆盖旧通知。如果需要保留多条通知,建议使用唯一ID(比如FCM消息的messageId或时间戳)。
内容的提问来源于stack exchange,提问作者stroopwafel
相关产品推荐
相关产品推荐

