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

MAUI 8应用后台时自定义Firebase云消息通知音效问题

在MAUI 8中自定义FCM后台通知音效(应用未启动时)

问题背景

需要在MAUI 8应用未启动时,自定义Firebase Cloud Messaging(FCM)推送通知的音效。当前后端使用Firebase Admin发送通知,MAUI端通过Plugin.Firebase处理通知。

后端发送通知代码

await FirebaseMessaging.DefaultInstance.SendAsync(new Message()
{
    Token = fcmtoken,
    Notification = new Notification()
    {
        Title = title,
        Body = body
    }
});

MAUI 8应用处理通知代码

FirebaseCloudMessagingImplementation.ShowLocalNotificationAction = notification =>
{
    var intent = PackageManager.GetLaunchIntentForPackage(PackageName);
    intent.PutExtra(FirebaseCloudMessagingImplementation.IntentKeyFCMNotification, notification.ToBundle());
    intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);

    var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.Immutable | PendingIntentFlags.UpdateCurrent);
    var builder = new NotificationCompat.Builder(this, channelId)
        .SetSmallIcon(Android.Resource.Drawable.SymDefAppIcon)
        .SetContentTitle(notification.Title)
        .SetContentText(notification.Body)
        .SetPriority(NotificationCompat.PriorityDefault)
        .SetAutoCancel(true);
    System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow();
    var notificationManager = (NotificationManager)GetSystemService(NotificationService);
    notificationManager.Notify(123, builder.SetContentIntent(pendingIntent).Build());
};

当前问题

应用运行时,通知通过自定义NotificationChannel推送,可自定义音效;但应用未启动时,通知由Google Play Services自动创建的默认渠道推送,无法自定义音效,如何覆盖应用未启动时的通知行为?


解决方案

核心原因:应用未启动时,FCM通知消息直接由Google Play Services处理,不会触发MAUI中设置的ShowLocalNotificationAction回调。需通过以下两种方式解决:

1. 强制指定自定义通知渠道

确保FCM消息使用预先创建的自定义渠道,该渠道需在应用首次启动时就完成初始化。

步骤1:在MAUI Android项目中创建自定义通知渠道

在MainApplication.cs的OnCreate方法中添加渠道初始化逻辑:

protected override void OnCreate()
{
    base.OnCreate();
    InitializeNotificationChannel();
}

private void InitializeNotificationChannel()
{
    if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
    {
        const string channelId = "custom_fcm_channel"; // 与通知Builder中的channelId保持一致
        const string channelName = "FCM推送通知";
        const string channelDesc = "接收FCM推送的自定义渠道";
        var importance = NotificationImportance.Default;

        // 创建渠道并设置自定义音效
        var channel = new NotificationChannel(channelId, channelName, importance)
        {
            Description = channelDesc,
            Sound = Uri.Parse($"android.resource://{PackageName}/{Resource.Raw.custom_notification_sound}")
        };

        // 配置音效的音频属性
        var audioAttributes = new AudioAttributes.Builder()
            .SetContentType(AudioContentType.Sonification)
            .SetUsage(AudioUsageKind.Notification)
            .Build();
        channel.SetAudioAttributes(audioAttributes);

        var notificationManager = (NotificationManager)GetSystemService(NotificationService);
        notificationManager.CreateNotificationChannel(channel);
    }
}

注意:将custom_notification_sound替换为你放在Resources/Raw目录下的音频文件名,且需将该文件的Android资源类型设置为AndroidResource。

步骤2:后端发送消息时指定渠道ID

修改后端FCM消息发送代码,添加AndroidConfig指定自定义渠道ID:

await FirebaseMessaging.DefaultInstance.SendAsync(new Message()
{
    Token = fcmtoken,
    Notification = new Notification()
    {
        Title = title,
        Body = body
    },
    Android = new AndroidConfig()
    {
        Notification = new AndroidNotification()
        {
            ChannelId = "custom_fcm_channel" // 与MAUI中创建的渠道ID一致
        }
    }
});

此方式下,即使应用未启动,Google Play Services也会使用指定的自定义渠道展示通知,自动继承渠道的音效设置。

2. 改用数据消息完全接管通知逻辑(更灵活)

将后端发送的通知消息改为数据消息,数据消息会被FCM传递到MAUI的MessageReceived回调,无论应用是否启动都会触发(需配置后台服务支持)。

后端发送数据消息示例

await FirebaseMessaging.DefaultInstance.SendAsync(new Message()
{
    Token = fcmtoken,
    Data = new Dictionary<string, string>()
    {
        {"title", title},
        {"body", body},
        {"sound", "custom_notification_sound"}
    }
});

MAUI中处理数据消息

在MainApplication.cs中注册消息接收回调,自行处理通知展示:

FirebaseCloudMessagingImplementation.MessageReceived += (sender, e) =>
{
    if (e.Data.TryGetValue("title", out var title) && e.Data.TryGetValue("body", out var body))
    {
        ShowCustomLocalNotification(title, body);
    }
};

private void ShowCustomLocalNotification(string title, string body)
{
    var intent = PackageManager.GetLaunchIntentForPackage(PackageName);
    intent.PutExtra(FirebaseCloudMessagingImplementation.IntentKeyFCMNotification, new Bundle());
    intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);

    var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.Immutable | PendingIntentFlags.UpdateCurrent);
    const string channelId = "custom_fcm_channel";
    var builder = new NotificationCompat.Builder(this, channelId)
        .SetSmallIcon(Android.Resource.Drawable.SymDefAppIcon)
        .SetContentTitle(title)
        .SetContentText(body)
        .SetPriority(NotificationCompat.PriorityDefault)
        .SetAutoCancel(true)
        .SetContentIntent(pendingIntent);

    var notificationManager = (NotificationManager)GetSystemService(NotificationService);
    notificationManager.Notify(123, builder.Build());
}

这种方式下,所有消息都会经过你的代码处理,完全控制通知的音效、样式等属性,不受应用运行状态影响。

关键注意事项

  • 通知渠道一旦创建,核心属性(如音效)无法修改,只能删除后重建,因此首次创建时需配置正确。
  • 自定义音效需符合Android格式要求(如MP3、WAV),文件大小不宜过大。
  • Android 13及以上需在AndroidManifest.xml中添加POST_NOTIFICATIONS权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:40:58