Xamarin.Android中FCM后台/关闭状态下更新应用角标问题
解决Xamarin.Android中ShortcutBadger在后台/关闭时不更新角标的问题
这个问题我之前也踩过坑,核心原因是Firebase通知的系统处理逻辑导致的,咱们一步步拆解解决:
为什么后台/关闭时失效?
当你的应用处于后台或完全关闭状态时,如果Firebase发送的是包含notification字段的通知消息,Android系统会直接接管通知的展示,不会把消息传递到OnMessageReceived方法里——这就意味着你写的ShortcutBadger.ApplyCount代码根本没机会执行,角标自然不会更新。
只有当Firebase发送的是纯数据消息(只有data字段,没有notification字段)时,系统才会在后台/关闭状态下触发OnMessageReceived,让你的代码有机会运行。
解决方案
方案1:改用Firebase数据消息发送
让你的后端发送纯数据消息(不要包含notification字段),这样不管应用处于前台还是后台,OnMessageReceived都会被触发,你可以在方法里自己构建通知,同时更新角标:
public override void OnMessageReceived(RemoteMessage message) { // 从data字段获取通知内容 var notificationBody = message.Data.ContainsKey("body") ? message.Data["body"] : "新通知"; var notificationTitle = message.Data.ContainsKey("title") ? message.Data["title"] : "通知"; // 更新角标计数(这里可以根据实际未读数量调整,比如从服务器拉取或本地维护) _UnreadNotifCount++; ShortcutBadger.ApplyCount(this, _UnreadNotifCount); // 手动构建并发送通知 SendNotification(notificationBody, message.Data); }
方案2:兼容含notification字段的消息(如果必须用这种格式)
如果后端没法改消息格式,那需要在应用启动时补全角标更新逻辑:
- 在应用的启动Activity(比如
MainActivity)的OnCreate方法中,读取当前未读通知的数量(可以存在SharedPreferences里,或者从服务器接口拉取),然后设置角标:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // ...其他初始化代码 // 获取未读数量(示例:从SharedPreferences读取) var prefs = GetSharedPreferences("AppPrefs", FileCreationMode.Private); int unreadCount = prefs.GetInt("UnreadNotifCount", 0); if (unreadCount > 0) { ShortcutBadger.ApplyCount(this, unreadCount); } }
- 在
OnMessageReceived中,除了更新角标,还要把未读数量保存到SharedPreferences,确保重启后能恢复:
public override void OnMessageReceived(RemoteMessage message) { _UnreadNotifCount++; ShortcutBadger.ApplyCount(this, _UnreadNotifCount); // 保存数量到本地 var prefs = GetSharedPreferences("AppPrefs", FileCreationMode.Private); var editor = prefs.Edit(); editor.PutInt("UnreadNotifCount", _UnreadNotifCount); editor.Apply(); SendNotification(message.GetNotification()?.Body, message.Data); }
- 当用户点击通知进入应用时,记得重置角标计数(如果需要):
// 比如在MainActivity的OnResume方法中 protected override void OnResume() { base.OnResume(); // 重置未读数量 _UnreadNotifCount = 0; ShortcutBadger.RemoveCount(this); // 更新本地存储 var prefs = GetSharedPreferences("AppPrefs", FileCreationMode.Private); var editor = prefs.Edit(); editor.PutInt("UnreadNotifCount", 0); editor.Apply(); }
额外注意:厂商适配
不同Android厂商的角标机制略有不同,ShortcutBadger已经做了大部分适配,但有些厂商可能需要额外配置:
- 小米:需要在AndroidManifest.xml中添加权限
<uses-permission android:name="com.xiaomi.push.permission.MIPUSH_RECEIVE" />,并确保应用在后台能正常接收推送。 - 华为:需要在华为开发者平台配置角标权限,或者使用华为官方的角标API配合ShortcutBadger。
- 三星:确保应用有通知权限,ShortcutBadger会自动处理。
内容的提问来源于stack exchange,提问作者ali
相关产品推荐
相关产品推荐

