Android应用前台运行时点击接收的FCM通知无响应问题求助
问题根因
- FCM推送的前后台处理逻辑存在差异:应用后台时,通知由FCM系统自动弹出,点击事件由Capacitor推送插件接管,所以你编写的
pushNotificationActionPerformed回调可以正常触发,跳转逻辑生效。 - 应用前台时,你在原生层的
onMessageReceived方法里自行构建通知弹出,这里的PendingIntent仅配置了跳转首页,既没有携带推送参数也没有和JS层的回调打通;同时原生层直接拦截了推送事件,没有抛给Capacitor插件,所以JS层的pushNotificationReceived收不到事件,点击通知自然也不会触发你写的跳转逻辑。 - 你原有代码里PendingIntent使用了0作为flag,Android 12及以上系统要求PendingIntent必须明确指定
FLAG_IMMUTABLE或FLAG_MUTABLE,否则会被系统判定为无效,这也是点击通知无响应的直接原因之一。
解决方法
方案一:保留原生层通知弹出逻辑,补全配置
修改onMessageReceived代码如下:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("message")); Intent intent = new Intent(this, MainActivity.class); // 把推送全量数据塞入Intent传递到页面 if (remoteMessage.getData() != null) { for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) { intent.putExtra(entry.getKey(), entry.getValue()); } } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // 适配高版本Android的PendingIntent强制flag要求 int pendingFlag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0; PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, pendingFlag); String channelId = "Default"; NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(remoteMessage.getNotification().getTitle()) .setContentText(remoteMessage.getNotification().getBody()) .setAutoCancel(true) .setContentIntent(pendingIntent); NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(channelId, "Default channel", NotificationManager.IMPORTANCE_DEFAULT); manager.createNotificationChannel(channel); } // 通知ID用时间戳避免新通知覆盖旧通知 int notifyId = (int) System.currentTimeMillis(); manager.notify(notifyId, builder.build()); }
同时在MainActivity中补充onNewIntent方法,接收通知传入的参数,传递给JS层执行跳转逻辑即可:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); // 此处判断如果是通知点击进入,将参数传递给JS层或者直接触发跳转逻辑即可 }
方案二:通知弹出逻辑完全交给JS层处理(更推荐,前后台逻辑统一)
删掉原生层onMessageReceived中自行构建通知的代码,仅保留日志打印即可,推送事件会自动抛给Capacitor的推送插件,此时JS层的pushNotificationReceived就可以正常触发,你在这个回调里调用createLocalNotification弹出本地通知即可,本地通知的点击事件会自动触发pushNotificationActionPerformed回调,和后台逻辑完全统一,不需要额外做原生适配。
额外检查项
- 你通过Postman调用FCM接口时,建议发送数据消息(即payload中仅包含data字段,不包含notification字段),如果包含notification字段,前台时会被系统直接拦截,不会触发
onMessageReceived和JS层的接收回调。 - 检查
AndroidManifest.xml中是否已经配置了FCM的服务和相关权限,以及MainActivity的启动模式是否配置正确。
内容的提问来源于stack exchange,提问作者Martin Rios
相关产品推荐
相关产品推荐

