.NET MAUI Android应用后台点击分组通知无法获取数据
问题描述
我正在用.NET MAUI开发Android应用,通过Google Firebase接收推送通知,遇到以下问题:
- 应用处于后台或被杀死状态时,通知抽屉内的多条通知会自动分组显示
- 点击未展开的分组通知时,
MainActivity的OnNewIntent()方法中,intent?.HasExtra("body")返回false,直接调用Intent.HasExtra("body")结果一致,且OnNewIntent()仅执行一次,无法获取任何通知数据 - 单条通知后台点击、展开分组后逐个点击通知,均能正常获取数据,
intent?.HasExtra("body")返回true - 应用前台时无此问题,该现象在Android模拟器和Pixel 7真机上均复现
MainActivity代码
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] public class MainActivity : MauiAppCompatActivity, Android.Gms.Tasks.IOnSuccessListener { public void OnSuccess(Java.Lang.Object result) { DeviceInstallationService.Token = result.ToString(); } // 应用后台时点击通知抽屉内的通知会触发此方法 protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); ProcessNotificationsAction(intent); } protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); if (DeviceInstallationService.NotificationsSupported) FirebaseMessaging.Instance.GetToken().AddOnSuccessListener(this); ProcessNotificationsAction(Intent); } private void ProcessNotificationsAction(Intent intent) { try { Task.Run(() => { if (intent?.HasExtra("body") == true) { var body = intent.GetStringExtra("body"); if (!string.IsNullOrEmpty(body)) { var id = Guid.Parse(intent.GetStringExtra("id")); var application = intent.GetStringExtra("application"); var datePublished = DateTime.SpecifyKind(DateTime.Parse(intent.GetStringExtra("datePublished")), DateTimeKind.Utc); NotificationMessageService.TriggerMessage(id, application, body, intent.HasExtra("url") ? intent.GetStringExtra("url") : null, datePublished); } } }); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } }
Firebase发送的消息内容
{ "message": { "notification": { "title": "Notification title", "body": "This is a test message..." }, "android": { "notification": { "channel_id": "com.company.app.default" } }, "data": { "id": "A GUID", "application": "App type A", "body": "This is a test message...", "url": "http://www...", "datePublished": "2024-11-08T00:00:00.0000000Z" } } }
环境与NuGet版本
- .NET MAUI - 8.0.82
- Microsoft.Maui.Controls - 8.0.82
- Microsoft.Maui.Controls.Compatibility - 8.0.82
- Xamarin.Firebase.Messaging 124.0.0.1
解决方案
这个问题的核心是:点击未展开的通知分组时,Android系统会发送汇总Intent,而非单个通知的Intent,因此无法获取到data字段内容。以下是三种可行的解决方式:
方式1:配置Firebase通知的分组点击行为
在发送的消息中,为Android通知添加分组相关配置,指定汇总通知的点击行为和携带数据:
{ "message": { "notification": { "title": "Notification title", "body": "This is a test message..." }, "android": { "notification": { "channel_id": "com.company.app.default", "group": "your_custom_group_id", "group_alert_behavior": "summary", "summary_notification": { "title": "新通知提醒", "body": "你有X条未读消息", "click_action": "OPEN_MAIN_ACTIVITY" } }, "data": { "id": "A GUID", "application": "App type A", "body": "This is a test message...", "url": "http://www...", "datePublished": "2024-11-08T00:00:00.0000000Z" } } } }
group_alert_behavior设为summary时,仅汇总通知会触发提醒;点击汇总通知时,会使用summary_notification配置的内容和点击行为。
方式2:在MainActivity中处理汇总Intent
当检测到是汇总Intent时,读取本地存储的最新通知数据进行处理:
修改ProcessNotificationsAction方法:
private void ProcessNotificationsAction(Intent intent) { try { Task.Run(() => { // 判断是否是分组汇总通知的Intent if (intent?.Action == "OPEN_MAIN_ACTIVITY" && !intent.HasExtra("body")) { // 从SharedPreferences读取本地存储的最新通知数据 var prefs = GetSharedPreferences("NotificationCache", FileCreationMode.Private); var lastBody = prefs.GetString("LastBody", null); var lastId = prefs.GetString("LastId", null); if (!string.IsNullOrEmpty(lastBody) && !string.IsNullOrEmpty(lastId)) { var id = Guid.Parse(lastId); var application = prefs.GetString("LastApp", null); var datePublished = DateTime.SpecifyKind(DateTime.Parse(prefs.GetString("LastDate", "")), DateTimeKind.Utc); var url = prefs.GetString("LastUrl", null); NotificationMessageService.TriggerMessage(id, application, lastBody, url, datePublished); } } else if (intent?.HasExtra("body") == true) { var body = intent.GetStringExtra("body"); if (!string.IsNullOrEmpty(body)) { var id = Guid.Parse(intent.GetStringExtra("id")); var application = intent.GetStringExtra("application"); var datePublished = DateTime.SpecifyKind(DateTime.Parse(intent.GetStringExtra("datePublished")), DateTimeKind.Utc); var url = intent.HasExtra("url") ? intent.GetStringExtra("url") : null; NotificationMessageService.TriggerMessage(id, application, body, url, datePublished); // 将当前通知数据存储到本地,供汇总通知点击时使用 var prefs = GetSharedPreferences("NotificationCache", FileCreationMode.Private); var editor = prefs.Edit(); editor.PutString("LastBody", body); editor.PutString("LastId", id.ToString()); editor.PutString("LastApp", application); editor.PutString("LastDate", datePublished.ToString("o")); editor.PutString("LastUrl", url); editor.Apply(); } } }); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } }
方式3:仅发送Data消息,自定义通知逻辑
放弃Firebase的默认通知展示,只发送data消息,完全自定义通知的创建和分组逻辑,确保所有通知(包括汇总通知)的Intent都携带所需数据:
{ "message": { "data": { "id": "A GUID", "application": "App type A", "body": "This is a test message...", "url": "http://www...", "datePublished": "2024-11-08T00:00:00.0000000Z", "title": "Notification title" }, "android": { "priority": "high" } } }
然后在自定义的FirebaseMessagingService的OnMessageReceived方法中,手动创建通知并处理分组逻辑,控制每个通知的Intent内容。
内容的提问来源于stack exchange,提问作者Koji
相关产品推荐
相关产品推荐

