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

在.NET MAUI中实现后台/关闭状态下接收FCM通知弹出弹窗

解决方案:FCM后台/关闭状态下触发弹窗Activity(.NET MAUI Android)

核心问题分析

你的问题根源有两个:

  1. Android 8.0(API 26)起限制后台直接启动Activity,普通BroadcastReceiver在应用后台/关闭时无法触发启动逻辑
  2. FCM消息分通知消息和数据消息:纯通知消息在后台时会被系统接管显示通知栏,不会触发自定义Receiver;只有数据消息会直接传递到应用,不受前台/后台状态影响

针对性解决步骤

1. 替换BroadcastReceiver为FirebaseMessagingService

FCM官方推荐使用FirebaseMessagingService处理消息,系统会在消息到达时自动唤醒Service,即使应用处于关闭状态。在.NET MAUI的Platforms/Android目录下创建以下类:

[Service(Exported = true)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FcmMessagingService : FirebaseMessagingService
{
    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        
        // 提取消息内容:优先取Data字段(数据消息),其次取Notification内容
        string messageContent = message.Data.TryGetValue("message", out var dataMsg) 
            ? dataMsg 
            : message.Notification?.Body ?? "收到新通知";

        // 启动弹窗Activity
        LaunchPopupActivity(messageContent);
    }

    private void LaunchPopupActivity(string message)
    {
        var intent = new Intent(this, typeof(ColorOverlayActivity));
        intent.PutExtra("message", message);

        // 设置Activity启动Flags,适配不同Android版本
        intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
        
        // Android 10+额外配置后台启动权限
        if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
        {
            intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.IncludeInRecents);
        }

        // 检查悬浮窗权限(Android 6.0+必须动态申请)
        if (Build.VERSION.SdkInt >= BuildVersionCodes.M && !Settings.CanDrawOverlays(this))
        {
            // 引导用户开启悬浮窗权限
            var permissionIntent = new Intent(Settings.ActionManageOverlayPermission,
                Android.Net.Uri.Parse($"package:{PackageName}"));
            permissionIntent.SetFlags(ActivityFlags.NewTask);
            StartActivity(permissionIntent);
            return;
        }

        StartActivity(intent);
    }
}

2. 配置弹窗Activity的Theme和Manifest

在Platforms/Android/Resources/values/styles.xml中定义悬浮窗主题:

<style name="OverlayTheme" parent="Theme.MaterialComponents.Light.Dialog">
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>

在Platforms/Android/AndroidManifest.xml中添加权限和组件注册:

<!-- 基础权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<!-- 悬浮窗权限(Android 6.0+) -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<!-- Android 12+后台启动权限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

<application ...>
    <!-- 注册FCM服务 -->
    <service android:name=".FcmMessagingService" android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <!-- 注册弹窗Activity -->
    <activity android:name=".ColorOverlayActivity"
              android:theme="@style/OverlayTheme"
              android:excludeFromRecents="true"
              android:noHistory="true"
              android:launchMode="singleInstance"
              android:exported="true" />
</application>

3. 确保服务器发送FCM数据消息

服务器端发送的FCM消息必须包含data字段(纯数据消息或混合消息),示例JSON格式:

{
  "to": "设备FCM令牌",
  "data": {
    "message": "这是要显示的弹窗内容",
    "title": "通知标题"
  }
}

如果发送纯notification字段的消息,后台状态下会被系统直接显示通知栏,不会触发你的自定义逻辑。

.NET MAUI额外注意事项

  • 确保已安装FCM相关NuGet包(如Xamarin.Firebase.Messaging或MAUI专用的FCM集成包)
  • 所有Android平台代码必须放在Platforms/Android目录下,MAUI构建系统会自动识别
  • 测试时关闭应用的电池优化限制,否则系统可能不会唤醒Service处理FCM消息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:15:22