在.NET MAUI中实现后台/关闭状态下接收FCM通知弹出弹窗
解决方案:FCM后台/关闭状态下触发弹窗Activity(.NET MAUI Android)
核心问题分析
你的问题根源有两个:
- Android 8.0(API 26)起限制后台直接启动Activity,普通
BroadcastReceiver在应用后台/关闭时无法触发启动逻辑 - 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
相关产品推荐
相关产品推荐

