You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于FCM主题的Android Studio自定义通知声音设置问题

解决FCM主题通知自定义声音的方案

嗨,既然你已经搞定了FCM主题的配置和基础通知,要实现不同主题对应不同自定义声音其实很简单,主要分两步走:

1. 推送消息时携带主题标识

首先得让后端在发送FCM主题通知时,在data字段里带上主题的专属标识(比如"topic": "A"或者"topic": "B")。这样客户端收到消息时,就能精准识别这条通知属于哪个主题,从而匹配对应的声音。

举个后端发送主题A消息的示例(伪代码):

{
  "to": "/topics/A",
  "data": {
    "message": "这是主题A的通知内容",
    "topic": "A",
    "link": "xxx",
    // 其他自定义字段...
  }
}

2. 客户端修改通知逻辑,根据主题匹配声音

接下来调整你的sendNotification方法,加入主题判断逻辑,根据主题值加载对应的自定义声音文件。

前置准备

先把你的声音文件(hello.mp3merra.mp3)放到项目的res/raw目录下——如果没有raw目录,直接在res文件夹下新建一个就行。

修改后的代码示例

// 先在接收FCM消息的方法里,从RemoteMessage中提取主题标识
private void handleFCMMessage(RemoteMessage remoteMessage) {
    String messageBody = remoteMessage.getData().get("message");
    String link = remoteMessage.getData().get("link");
    String topic = remoteMessage.getData().get("topic"); // 获取主题标识
    // 这里可以处理图片逻辑,比如解析remoteMessage里的图片链接生成Bitmap
    Bitmap image = null; // 替换成你的图片处理代码
    sendNotification(messageBody, image, link, topic);
}

// 给sendNotification方法增加topic参数,用于判断要播放的声音
private void sendNotification(String messageBody, Bitmap image, String link, String topic) {
    Intent intent = new Intent(this, FullscreenActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("LINK", link);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* 请求码 */, intent,
            PendingIntent.FLAG_IMMUTABLE);

    // 根据主题选择对应的声音Uri
    Uri soundUri;
    if ("A".equals(topic)) {
        soundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.hello);
    } else if ("B".equals(topic)) {
        soundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.merra);
    } else {
        // 没有匹配到主题时,用系统默认通知音
        soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    }

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "你的通知渠道ID")
            .setSmallIcon(R.drawable.ic_notification)
            .setContentTitle("通知标题")
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(soundUri) // 设置自定义声音
            .setContentIntent(pendingIntent);

    // 如果有图片,添加大图展示逻辑
    if (image != null) {
        notificationBuilder.setLargeIcon(image);
        notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image));
    }

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

    // 适配Android 8.0及以上的通知渠道(必须设置,否则自定义声音可能不生效)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel("你的通知渠道ID",
                "通知渠道名称",
                NotificationManager.IMPORTANCE_DEFAULT);
        channel.setSound(soundUri, null); // 给渠道绑定对应声音
        notificationManager.createNotificationChannel(channel);
    }

    notificationManager.notify(0 /* 通知ID */, notificationBuilder.build());
}

关键注意事项

  • Android O+的通知渠道:8.0及以上系统必须给通知渠道也设置声音,否则自定义声音会失效,上面的代码已经包含了这部分逻辑。
  • 声音格式兼容性:确保你的mp3文件是Android支持的编码格式,避免出现无法播放的情况。
  • 主题标识一致性:后端发送的topic字段值,要和客户端判断的字符串完全一致(注意大小写敏感)。

这样设置后,主题A的通知就会播放hello.mp3,主题B的通知播放merra.mp3啦!

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

火山引擎 最新活动