Android通知PendingIntent异常:点击通知打开MainActivity而非TestActivity
问题排查与修复方案
核心问题根源
当应用处于完全关闭状态时,Firebase Cloud Messaging(FCM)的通知类型消息(payload包含notification字段)会由Android系统直接接管处理,不会触发你的onMessageReceived方法。系统会自动生成一个指向应用启动Activity(也就是你的MainActivity)的通知,这就是点击推送后打开MainActivity的原因。
只有纯数据类型消息(payload仅包含data字段)才会在应用关闭时触发onMessageReceived,让你的自定义通知逻辑生效。
具体修复步骤
1. 要求后端发送纯数据类型FCM消息
后端推送的payload必须只包含data字段,不能有notification字段。示例payload格式:
{ "to": "目标设备Token", "data": { "title": "通知标题", "description": "通知描述", "target": "test_activity" } }
这样无论应用处于前台、后台还是关闭状态,都会走你自定义的通知创建逻辑。
2. 调整PendingIntent配置
- 给PendingIntent设置唯一的requestCode,避免intent被系统复用覆盖。把之前固定的
0改成和通知ID一致的随机值:
val notifyPendingIntent = PendingIntent.getActivity( this, random, // 用生成的随机数作为requestCode,和通知ID保持一致 notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
- 优化TestActivity的启动标记,去掉可能导致任务栈异常的配置。如果不需要特殊的任务栈行为,暂时移除
launchMode和taskAffinity:
<activity android:name=".TestActivity" android:exported="false" android:excludeFromRecents="true"/>
(Android 12+需显式设置android:exported,这里TestActivity不需要外部启动,设为false即可)
3. 统一通知通道ID
你当前每次创建通知都用随机通道ID,会生成大量无效通道。固定一个通道ID:
// 定义全局常量 private const val NOTIFICATION_CHANNEL_ID = "test_notification_channel" // 创建通知时使用固定ID val notificationBuilder: NotificationCompat.Builder = NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) // 创建通道时也用这个ID private fun getChannel(): NotificationChannel { return NotificationChannel( NOTIFICATION_CHANNEL_ID, "测试通知通道", NotificationManager.IMPORTANCE_DEFAULT ).apply { description = "用于打开TestActivity的通知通道" } }
4. 验证Intent Flags
如果不需要清空整个任务栈,可调整Intent的flags,避免影响正常启动逻辑:
val notifyIntent = Intent(this, TestActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK }
测试流程
- 完全关闭应用(从最近任务列表中划掉)
- 发送纯数据类型的FCM消息
- 点击通知,确认是否正常打开TestActivity
内容的提问来源于stack exchange,提问作者wprpovhtguetbfdotm
相关产品推荐
相关产品推荐

