添加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
相关产品推荐
相关产品推荐

