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

Android中FCM通知:应用前台时如何显示全部通知

解决Android FCM前台通知互相覆盖的问题

通知互相覆盖的核心原因是多次发送通知时使用了相同的通知ID——Android系统会用新通知替换掉同ID的旧通知。要让前台显示所有通知,关键是为每个通知分配唯一的ID,具体实现步骤如下:

1. 为每个通知生成唯一ID

可以通过两种方式获取/生成唯一ID:

  • 从FCM消息的自定义数据中获取:如果服务器在发送FCM消息时,在data字段中携带唯一的消息标识(比如message_id),直接用这个值作为通知ID。
  • 本地生成唯一值:如果服务器没有提供唯一标识,可在本地用随机数、时间戳或UUID生成。

2. 前台消息的处理逻辑

当应用处于前台时,FCM不会自动弹出通知,需要在FirebaseMessagingService的onMessageReceived方法中手动构建并发送通知,同时传入唯一ID。

完整代码示例

第一步:实现应用前台状态判断

在自定义Application类中注册生命周期回调,跟踪应用是否在前台:

public class MyApp extends Application implements Application.ActivityLifecycleCallbacks {
    private static boolean isAppForeground = false;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onActivityResumed(Activity activity) {
        isAppForeground = true;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        isAppForeground = false;
    }

    // 其余生命周期方法留空实现即可
    @Override public void onActivityCreated(Activity activity) {}
    @Override public void onActivityStarted(Activity activity) {}
    @Override public void onActivityStopped(Activity activity) {}
    @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
    @Override public void onActivityDestroyed(Activity activity) {}

    public static boolean isAppInForeground() {
        return isAppForeground;
    }
}

第二步:在FirebaseMessagingService中处理前台通知

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        if (MyApp.isAppInForeground()) {
            // 提取通知内容
            String title = remoteMessage.getNotification() != null ? remoteMessage.getNotification().getTitle() : "通知";
            String body = remoteMessage.getNotification() != null ? remoteMessage.getNotification().getBody() : "";

            // 获取/生成唯一通知ID
            int notificationId;
            // 优先使用服务器传来的message_id
            if (remoteMessage.getData().containsKey("message_id")) {
                try {
                    notificationId = Integer.parseInt(remoteMessage.getData().get("message_id"));
                } catch (NumberFormatException e) {
                    // 解析失败则生成随机ID
                    notificationId = new Random().nextInt(Integer.MAX_VALUE);
                }
            } else {
                // 本地生成唯一ID,这里用时间戳
                notificationId = (int) System.currentTimeMillis();
            }

            // 构建通知(确保已创建对应通知渠道)
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "YOUR_CHANNEL_ID")
                    .setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle(title)
                    .setContentText(body)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                    .setAutoCancel(true);

            // 发送通知,传入唯一ID
            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
            notificationManager.notify(notificationId, builder.build());
        }
    }
}

3. 注意事项

  • 通知渠道:Android 8.0(API 26)及以上必须创建通知渠道,否则通知无法显示。可在应用启动时初始化渠道:
private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = "通知渠道名称";
        String description = "通知渠道描述";
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel("YOUR_CHANNEL_ID", name, importance);
        channel.setDescription(description);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}
  • 数据消息 vs 通知消息:如果服务器发送的是纯data消息,无论应用前后台都会触发onMessageReceived,处理逻辑和上述一致;如果是notification消息,后台时FCM会自动显示通知,前台则需要手动处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:15:30