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

添加Pending Intent后重复接收Push Notification如何解决?

解决推送通知重复接收问题

你遇到的重复接收通知问题,核心原因大概率是推送服务本身已经自动展示通知,而你的代码又手动调用了一次notify()方法重复显示,或是通知ID固定导致的逻辑冲突,以下是具体解决步骤:

1. 区分推送消息类型,避免重复触发展示

如果使用的是FCM这类主流推送服务,消息分为两类:

  • 通知消息:由系统自动展示,无需手动调用sendNotification
  • 数据消息:需要开发者手动处理并展示通知

你的代码里判断了remoteMessage.getNotification() != null,说明当前处理的是通知消息——这类消息系统会自动弹出通知,你再调用notifManager.notify()就会导致重复显示。

解决方法:

  • 要么推送后台只发送数据消息,由你的代码统一处理展示;
  • 要么配置客户端拦截通知消息,禁用系统自动展示的行为,完全走自定义逻辑。

2. 使用唯一通知ID

代码中固定的NOTIFY_ID = 1002会导致新通知覆盖旧通知,同时也可能和系统自动展示的通知ID冲突。改用你已经定义的动态ID即可:

// 替换固定ID为动态生成的唯一值
notifManager.notify(notification_id, notification);

3. 优化PendingIntent避免复用冲突

当前PendingIntent的requestCode为0,相似Intent会被复用,可能引发异常行为。改用动态值并添加适配高版本的标记:

// 用通知ID作为requestCode,同时添加Android 12+要求的标记
pendingIntent = PendingIntent.getActivity(this, notification_id, notificationIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);

完整修改后的代码示例

private void sendNotification(RemoteMessage remoteMessage) {
    // 生成唯一通知ID
    int notification_id = (int) System.currentTimeMillis();

    // 兼容通知消息和数据消息的标题/内容获取
    String title = remoteMessage.getData().get("title") != null ? remoteMessage.getData().get("title") : remoteMessage.getNotification().getTitle();
    String body = remoteMessage.getData().get("body") != null ? remoteMessage.getData().get("body") : remoteMessage.getNotification().getBody();
    String type = remoteMessage.getData().get("type");
    String name = "my_package_channel";
    String id = "my_package_channel_1";
    String description = "my_package_first_channel";

    Intent notificationIntent = new Intent(this, SplashScreen.class);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    notificationIntent.putExtra("isNotification", true);
    // 优化PendingIntent参数
    PendingIntent pendingIntent = PendingIntent.getActivity(this, notification_id, notificationIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);

    NotificationManager notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // 处理Android 8.0+的通知渠道
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel mChannel = notifManager.getNotificationChannel(id);
        if (mChannel == null) {
            mChannel = new NotificationChannel(id, name, importance);
            mChannel.setDescription(description);
            mChannel.enableVibration(true);
            mChannel.setLightColor(Color.GREEN);
            mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            notifManager.createNotificationChannel(mChannel);
        }
    }

    // 统一构建通知(避免版本分支冗余)
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, id)
            .setContentTitle(title)
            .setSmallIcon(R.drawable.eyeplus_logo)
            .setContentText(body)
            .setDefaults(Notification.DEFAULT_ALL)
            .setAutoCancel(true)
            .setTicker(title)
            .setContentIntent(pendingIntent)
            .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        builder.setPriority(Notification.PRIORITY_HIGH);
    }

    Notification notification = builder.build();
    // 使用唯一ID发送通知
    notifManager.notify(notification_id, notification);
}

额外排查点

  • 检查推送后台是否重复发送了同一条消息;
  • 确认FirebaseMessagingService的onMessageReceived是否被多次触发;
  • 排查代码中是否有其他地方也调用了通知展示逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:44:53