从Android通知启动Activity并传递Extra参数问题排查
问题分析与解决方案
问题原因
你遇到的问题根源在于使用了TaskStackBuilder.addNextIntentWithParentStack()方法。这个方法会根据AndroidManifest中配置的Activity父子关系自动构建任务栈的Intent链,其中会包含启动应用主界面的android.intent.action.MAIN Intent。当ResultActivity首次启动、任务栈为空时,系统会优先使用这个自动生成的主界面Intent初始化任务栈,导致你自定义的action和extra参数被覆盖,最终拿到的是不带参数的MAIN Intent。
解决方案
方案1:无需构建完整任务栈时(直接启动ResultActivity)
如果不需要点击返回键回到主界面,直接跳过TaskStackBuilder,用普通方式创建PendingIntent即可:
private fun getNotificationContentItem(notificationId: String): PendingIntent? { val notificationIntent = Intent(this, ResultActivity::class.java) notificationIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP notificationIntent.action = ACTION_START_NOTIFICATION_DETAILS notificationIntent.putExtra(EXTRA_NAME_NOTIFICATION_ID, notificationId) var flags = PendingIntent.FLAG_CANCEL_CURRENT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { flags = flags or PendingIntent.FLAG_IMMUTABLE } // 直接创建Activity类型的PendingIntent,无需TaskStackBuilder return PendingIntent.getActivity(this, 0, notificationIntent, flags) }
方案2:需要构建完整任务栈时(返回键回到主界面)
如果需要保持任务栈结构(比如点击ResultActivity的返回键回到主界面),需要手动构建任务栈的Intent链,避免自动生成的MAIN Intent覆盖参数:
- 先在AndroidManifest中配置ResultActivity的父Activity(假设主界面是MainActivity):
<activity android:name=".ResultActivity" android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity>
- 修改
getNotificationContentItem方法,手动添加栈内的每个Intent:
private fun getNotificationContentItem(notificationId: String): PendingIntent? { // 创建主界面Intent,确保栈底正确 val mainIntent = Intent(this, MainActivity::class.java) mainIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP // 创建带参数的ResultActivity Intent val resultIntent = Intent(this, ResultActivity::class.java) resultIntent.action = ACTION_START_NOTIFICATION_DETAILS resultIntent.putExtra(EXTRA_NAME_NOTIFICATION_ID, notificationId) resultIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP var flags = PendingIntent.FLAG_CANCEL_CURRENT if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { flags = flags or PendingIntent.FLAG_IMMUTABLE } val builder = TaskStackBuilder.create(this) // 先添加主界面到栈底 builder.addNextIntent(mainIntent) // 再添加目标ResultActivity builder.addNextIntent(resultIntent) return builder.getPendingIntent(0, flags) }
补充:Activity中正确获取参数
由于设置了FLAG_ACTIVITY_SINGLE_TOP,当ResultActivity已存在时,新Intent会通过onNewIntent()传递,所以需要同时处理onCreate()和onNewIntent():
class ResultActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_result) handleIntent(intent) } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) setIntent(intent) // 更新当前Intent为最新的 handleIntent(intent) } private fun handleIntent(intent: Intent?) { intent?.let { val notificationId = it.getStringExtra(EXTRA_NAME_NOTIFICATION_ID) val action = it.action // 这里处理你的业务逻辑 } } }
内容的提问来源于stack exchange,提问作者almasif
相关产品推荐
相关产品推荐

