无法从通知Intent获取Extras,求技术解决方案(附代码)
Android推送通知Extras获取为null的问题排查与解决
问题场景
在Android项目中基于FirebaseMessagingService实现推送通知,已为通知PendingIntent对应的Intent添加了Extras,但在MainActivity中获取这些Extras时始终返回null。尝试过修改Activity的launchMode、调整Intent标志位等方法,问题仍未解决。
核心问题点
- PendingIntent复用导致Extras未更新:当前使用固定的
requestCode=0创建PendingIntent,系统会复用已存在的PendingIntent实例,新添加的Extras无法覆盖旧数据。 - Intent启动标志缺失:Activity设置为
singleTop模式,但未给Intent添加FLAG_ACTIVITY_SINGLE_TOP | FLAG_ACTIVITY_CLEAR_TOP标志,导致栈顶的Activity无法接收新的Intent数据。 - onNewIntent未更新Activity的Intent实例:收到新Intent时未调用
setIntent(intent),后续调用intent获取的仍是旧实例,自然读不到新Extras。
解决方案
- 使用唯一的PendingIntent requestCode:避免复用旧的PendingIntent,确保每次创建的PendingIntent都携带最新的Extras。
- 添加正确的Intent启动标志:让Activity在栈顶时能接收新Intent,同时清理栈内多余的Activity实例。
- 在onNewIntent中更新Activity的Intent:确保后续调用
intent时能获取到最新的Intent数据。 - 保留FLAG_UPDATE_CURRENT标志:确保已存在的PendingIntent能更新Extras内容。
修改后的FirebaseMessagingService关键代码
private fun generateNotification(title: String, message: String) { val notifIntent = Intent(this, MainActivity::class.java) val channelId = Resources.getSystem().getString(R.string.default_notification_channel_id) notifIntent.putExtra(DESTINATION_PUSH_KEY, 2) notifIntent.putExtra("some_key", "2") // 添加启动标志,适配singleTop模式 notifIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) // 使用唯一requestCode,避免PendingIntent复用 val requestCode = System.currentTimeMillis().toInt() val pendingIntent: PendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { PendingIntent.getActivity( this, requestCode, notifIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) } else { PendingIntent.getActivity( this, requestCode, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT ) } // 以下Notification构建代码保持不变... }
修改后的MainActivity onNewIntent方法
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) // 更新Activity的Intent为最新的实例 intent?.let { setIntent(it) processIntent(it) } }
补充:冷启动场景处理
如果应用从完全关闭状态通过通知打开,需要在onCreate中也处理Intent:
override fun onCreate(savedInstanceState: Bundle?) { // 原有初始化代码... intent?.let { processIntent(it) } }
内容的提问来源于stack exchange,提问作者Евгений Гарифуллин
相关产品推荐
相关产品推荐

