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

应用被杀死时FCM推送未触发onMessageReceive问题求助

解决FCM杀死状态下onMessageReceived不触发、音效仅播放一次的问题

我来帮你搞定这个问题,核心原因其实和FCM的消息分发机制有关,先给你理清楚:

问题根源

当你同时发送Notification消息和Data消息时,FCM的处理逻辑是这样的:

  • 应用前台状态:onMessageReceived会被触发,你能拿到所有Data和Notification内容
  • 应用后台/杀死状态:系统会自动帮你展示Notification消息,而Data消息会被附加到通知的跳转Intent里,不会触发onMessageReceived
    这就是为什么你在应用杀死时,onMessageReceived没执行,音效只播放了一次——那其实是系统默认通知的音效,不是你自己的SoundIntentService触发的。

解决方案

最靠谱的解决方式是只发送纯Data消息,把通知的展示和音效播放完全交给客户端自己处理,这样不管应用处于什么状态,onMessageReceived都会被触发。

1. 调整云服务器的推送消息结构

去掉notification字段,只保留data字段,示例格式如下:

{
  "to": "你的设备Token",
  "data": {
    "orderId": "12345",
    "orderType": "外卖",
    "orderStatus": "待接单"
  }
}

2. 修改MyFirebaseMessagingService的逻辑

在onMessageReceived里自己构建自定义通知,同时启动你的音效服务,确保每次收到推送都能触发音效:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.e("@@", ">>>>>>>>>: Inside CLASS");
    Log.e("@@", ">>>>>>>>>: Inside ON MESSAGE RECEIVED");
    
    Map<String, String> data = remoteMessage.getData();
    String orderID = data.get("orderId");
    String orderType = data.get("orderType");
    String orderStatus = data.get("orderStatus");

    // 1. 构建自定义通知(适配Android O及以上的渠道要求)
    Intent activityIntent = new Intent(this, MainActivity.class); // 替换成你的目标Activity
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 
            0, 
            activityIntent, 
            PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE
    );

    String channelId = "order_notification_channel";
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_notification) // 替换成你的通知图标
            .setContentTitle("新订单提醒")
            .setContentText("订单ID:" + orderID + " | 类型:" + orderType)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent);

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

    // 创建通知渠道(Android O+必须)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                channelId,
                "订单通知",
                NotificationManager.IMPORTANCE_HIGH
        );
        notificationManager.createNotificationChannel(channel);
    }

    // 展示通知
    notificationManager.notify((int) System.currentTimeMillis(), notificationBuilder.build());

    // 2. 启动音效服务(适配Android O+的前台服务要求)
    Intent soundServiceIntent = new Intent(getApplicationContext(), SoundIntentService.class);
    // 可传递订单参数给服务
    soundServiceIntent.putExtra("orderId", orderID);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(soundServiceIntent);
    } else {
        startService(soundServiceIntent);
    }
}

3. 优化SoundIntentService的稳定性

为了确保音效能持续播放且不被系统轻易回收,建议:

  • 在onStartCommand中返回START_STICKY,这样服务被杀死后能尝试重启
  • Android O及以上版本中,把服务设为前台服务(显示一个前台通知),避免被系统后台限制杀死

备选方案(不推荐)

如果必须保留Notification消息的发送,那只能在用户点击通知时,在跳转的Activity中获取Data参数,再启动音效服务。但这种方式无法在收到推送时自动播放音效,只能等用户点击,体验不好,所以还是优先用纯Data消息的方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:54