You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Media3:点击媒体通知启动应用,PendingIntent附加数据丢失

问题分析与解决方案

核心问题根源

  1. getLaunchIntentForPackage的局限性
    该方法返回的是应用默认的启动Intent(带有MAIN/LAUNCHER过滤器),当应用已处于前台时,系统会复用栈顶的MainActivity实例,默认不会传递新Intent的extras——除非Activity配置了特定启动模式并正确处理新Intent。

  2. 未处理onNewIntent生命周期回调
    当Activity以singleTop/singleTask模式运行且已在栈顶时,系统不会重新创建实例,而是调用onNewIntent传递新Intent。如果未重写该方法并更新Activity的Intent引用,onStart中获取的始终是旧Intent,自然拿不到新的extras。


具体修复步骤

1. 改用显式Intent替代默认启动Intent

避免依赖getLaunchIntentForPackage,直接创建指向MainActivity的显式Intent,确保extras能被正确传递:

// 在MediaSessionService的onCreate中修改intent创建逻辑
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("DESTINATION", "player")
// 添加flags确保行为可控
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)

val pendingIntent = PendingIntent.getActivity(
    this, 
    0, 
    intent, 
    PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

mediaSession = MediaSession.Builder(this, player)
    .setSessionActivity(pendingIntent)
    .build()

2. 配置MainActivity的启动模式

在Manifest中给MainActivity添加singleTop启动模式,确保栈顶存在时复用实例并触发onNewIntent:

<!-- app模块的Manifest -->
<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"> <!-- 添加这行 -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

3. 重写MainActivity的onNewIntent方法

更新Activity的Intent引用并处理跳转逻辑:

class MainActivity : AppCompatActivity() {
    override fun onStart() {
        super.onStart()
        // 现在可以正确获取到最新的extras
        Timber.e("onStart: intents: ${intent.extras?.size()}")
        handleDestination(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // 必须更新Activity的intent变量,否则后续生命周期拿到的还是旧值
        setIntent(intent)
        handleDestination(intent)
    }

    private fun handleDestination(intent: Intent?) {
        intent?.getStringExtra("DESTINATION")?.let { destination ->
            if (destination == "player") {
                // 跳转至播放器UI的逻辑
            }
        }
    }
}

额外注意事项

  • API 34要求PendingIntent必须指定FLAG_IMMUTABLE或FLAG_MUTABLE,你当前使用的FLAG_IMMUTABLE符合要求。
  • 由于MainActivity和MediaSessionService分属不同模块,确保MainActivity的全类名在显式Intent中正确引用(如果存在包名差异,需使用完整包名+类名)。

内容的提问来源于stack exchange,提问作者rysv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 16:05:14