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

Android点击通知(PendingIntent)打开错误Activity的技术求助

解决FCM通知在应用关闭时跳转错误Activity的问题

这个问题我之前也踩过坑,核心原因是FCM通知消息的处理逻辑在应用不同状态下完全不一样:

当你的应用处于前台/后台时,onMessageReceived会被正常触发,你通过sendNotification创建的通知用了自定义的PendingIntent,所以点击能正确打开IntroNoti。但当应用完全关闭(进程被杀死)时,如果FCM消息是通知类型(也就是payload里包含notification字段),系统会直接接管通知的展示,这时候点击通知会默认打开你的启动页(Splash Activity),根本不会走你在onMessageReceived里设置的PendingIntent逻辑。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:改用FCM数据消息(最推荐)

让后端发送纯数据消息(payload里只包含data字段,不要notification字段),这样不管应用处于什么状态,onMessageReceived都会被触发,你可以完全自定义通知和跳转逻辑,不受系统默认行为干扰。

修改你的sendNotification方法,从remoteMessage.getData()里获取通知内容:

private void sendNotification(RemoteMessage remoteMessage) {
    // 从data字段提取通知标题和内容
    String title = remoteMessage.getData().get("title");
    String body = remoteMessage.getData().get("body");

    Intent intent = new Intent(this, IntroNoti.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
    // 把通知附带的数据传递给目标Activity
    intent.putExtras(remoteMessage.getData());

    // 注意添加FLAG_IMMUTABLE适配Android 12及以上版本
    PendingIntent pendingIntent = PendingIntent.getActivity(
        this, 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );

    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.ic_launcher: R.mipmap.ic_launcher;

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        .setSmallIcon(icon)
        .setContentTitle(title)
        .setContentText(body)
        .setAutoCancel(true)
        .setSound(defaultSoundUri)
        .setContentIntent(pendingIntent);

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, notificationBuilder.build());
}

方案2:在启动页(Splash Activity)中处理跳转

如果没法修改后端的消息发送格式,那可以在你的Splash Activity里加一层判断:如果是从FCM通知点击进来的,就直接跳转到IntroNoti,跳过原本的启动逻辑。

在Splash的onCreate方法里添加:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    // 检查是否是从FCM通知跳转过来的
    Intent incomingIntent = getIntent();
    if (incomingIntent != null && incomingIntent.getExtras() != null) {
        // 可以根据通知里的特定参数判断是否需要跳转,比如检查是否有"target_page"之类的字段
        Intent targetIntent = new Intent(this, IntroNoti.class);
        targetIntent.putExtras(incomingIntent.getExtras());
        startActivity(targetIntent);
        finish(); // 直接关闭Splash页,不让它走后续逻辑
        return;
    }

    // 原来的Splash初始化逻辑,比如跳转到主页
    // ...
}

方案3:使用TaskStackBuilder构建正确的任务栈

如果你想保留通知消息的发送方式,也可以用TaskStackBuilder来构建符合预期的任务栈,确保应用关闭时点击通知能直接打开目标Activity。

修改sendNotification里的PendingIntent创建部分:

Intent intent = new Intent(this, IntroNoti.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

// 用TaskStackBuilder构建包含父Activity的任务栈
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(intent);
// 同样要加FLAG_IMMUTABLE适配高版本
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

这个方案需要你在Manifest里给IntroNoti设置正确的父Activity,比如:

<activity android:name=".IntroNoti">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".SplashActivity"/>
</activity>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:39:22