You need to enable JavaScript to run this app. Android FCM推送通知弹出时无声音的问题排查咨询
优惠活动
大模型
产品
解决方案
定价
更多

Android FCM推送通知弹出时无声音的问题排查咨询

FCM推送通知无提示音问题的原因排查与修复方案

核心问题根源

  1. Android 8.0+ 通知机制适配失效
    当前OreoNotification类的实现,把声音配置写在了Notification.Builder里,但从API 26(Android 8.0)开始,通知的声音、震动、播放优先级权限完全绑定在通知渠道(Notification Channel)上:渠道一旦创建,所有相关配置会被系统固化,单独给Notification实例设置的sound、vibrate参数都会被直接忽略。
    你当前创建渠道的代码中,完全缺失渠道级别的声音配置,自然会导致通知静默。
    更易踩坑的细节:通知渠道创建后无法通过代码修改配置,如果之前安装过对应CHANNEL_ID的旧版本APP,就算后续改了渠道逻辑,只要不更换渠道ID,旧的静默配置依然会生效。

  2. FCM消息触发逻辑被系统截断
    如果后端发送的FCM消息同时携带notification节点和data节点的混合内容,当APP处于后台、进程被杀死的状态时,FCM SDK会直接读取notification节点的内容,通过系统默认渠道自动生成通知,完全不会执行你自定义的MyFirebaseMessaging类中的通知构建逻辑,这时候你写的所有声音配置都不会生效。

  3. 系统适配的隐性限制
    部分国产定制ROM(小米、OPPO、vivo等)对通知的校验更严格:如果渠道重要等级设置为IMPORTANCE_DEFAULT、没有搭配对应音频属性,就算用系统默认渠道,也可能被ROM归为静默通知拦截声音;低版本(API<26)通知如果没设置高优先级,也可能被系统归为静默通知不播声音。
    另外Android 12以上对PendingIntent的可变性有强制要求,如果没指定对应flag,通知会被系统拦截,连带声音也不会触发。

可落地的修复步骤

  • 重构8.0+版本的通知渠道配置

    1. 更换全新的CHANNEL_ID(比如把原来的"some_id"改为"selfcial_message_channel_v2"),避免旧渠道的固化配置影响新逻辑。
    2. 在createChannel()方法中完成渠道级的声音配置,删除无效的Notification级声音设置:
      @TargetApi(Build.VERSION_CODES.O)
      private void createChannel() {
          Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
          // 构建标准音频属性,适配全机型的声音播放规则
          AudioAttributes audioAttributes = new AudioAttributes.Builder()
                  .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                  .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                  .build();
      
          NotificationChannel channel = new NotificationChannel(
                  CHANNEL_ID,
                  CHANNEL_NAME,
                  // 提升渠道重要等级为高优先级,确保通知能正常弹窗、播声音
                  NotificationManager.IMPORTANCE_HIGH
          );
          channel.enableLights(true);
          channel.enableVibration(true);
          // 渠道级绑定声音配置,这才是8.0以上系统实际生效的声音参数
          channel.setSound(soundUri, audioAttributes);
          channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
      
          getManager().createNotificationChannel(channel);
      }
      
    3. 删掉getOreoNotification()方法中无效的.setSound(soundUri)配置,避免混淆判断逻辑。
  • 调整FCM消息的发送结构
    通知后端发送纯data结构的FCM消息,即请求体中仅保留data字段,不携带notification字段。这样无论APP在前台、后台还是进程被杀死,消息都会被投递到你自定义的MyFirebaseMessaging的onMessageReceived方法中,完全走你自定义的通知构建流程,不会被系统自动截断用默认渠道生成静默通知。
    如果必须保留notification节点,需要在节点中显式指定sound参数为对应的提示音路径,确保系统自动生成通知时能正常播放声音。

  • 补充低版本和高版本的兼容配置

    1. 给API<26分支的NotificationCompat.Builder补充高优先级配置,避免被系统归为静默通知:
      NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
              .setSmallIcon(R.drawable.ic_notification)
              .setContentTitle(title)
              .setContentText(body)
              .setAutoCancel(true)
              .setSound(soundUri)
              // 新增高优先级配置
              .setPriority(NotificationCompat.PRIORITY_HIGH)
              .setContentIntent(pendingIntent);
      
    2. 给所有PendingIntent调用补充Android 12要求的可变性flag,避免通知被系统拦截:
      PendingIntent pendingIntent = PendingIntent.getActivity(
          this, j, intent, 
          // 补充FLAG_IMMUTABLE,适配Android 12+的规则
          PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE
      );
      
  • 最后做真机排查:确认APP的系统通知开关、对应通知渠道的“允许播放提示音”“允许振动”开关处于打开状态,部分国产ROM默认会把第三方APP的通知渠道设为静默,需要手动确认开关状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 02:36:04