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

Xamarin Forms Android前台模式始终读取初始通知数据的问题求助

Xamarin Forms Android前台模式始终读取初始通知数据的问题求助

各位大佬好,我最近在做Xamarin Forms Android的FCM通知功能,碰到了一个棘手的问题:APP处于前台模式时,每次点击新通知,总是读取到第一次收到的通知数据,新通知的内容根本读不出来,但后台/APP被杀死的状态下一切正常。下面是我的整个实现过程和问题复现步骤,麻烦大家帮忙排查一下!

我的FCM通知Payload示例

先贴一下我用的通知Payload,需要读取commentMessageType、revealedLocationName、revealedLocationId和嵌套的requestData字段:

{
  "to" : "device-fcm-token",
  "notification" : {
    "body" : "Hiii",
    "title": "Title"
  },
  "data" : {
    "commentMessageType": "customer",
    "revealedLocationName": "Moncy Events Center",
    "revealedLocationId": "77451",
    "requestData": {
      "request": {
        "itemId": 3226,
        "itemTitle": "Need car maintanance service",
        "itemDescription": "Need car maintanance service",
        "itemType": "request",
        "itemStatus": 1,
        "itemSource": 0,
        "itemPriority": 1
      },
      "category": "Vehicle Rental",
      "companyId": 0,
      "companyName": null
    }
  }
}

我已实现的代码逻辑

1. 发送通知的SendNotificatios方法

我已经修改了这个方法,把通知的data参数传入并添加到Intent的Extra中,确保点击通知时能携带数据:

public void SendNotificatios(string body, string Header, IDictionary<string, string> data)
{
    var intent = new Intent(this, typeof(MainActivity));
    intent.AddFlags(ActivityFlags.ClearTop);

    // 将通知data中的所有字段加入Intent Extra
    foreach (var key in data.Keys)
    {
        intent.PutExtra(key, data[key]);
    }

    var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.Mutable);

    if (Build.VERSION.SdkInt < BuildVersionCodes.O)
    {
        var notificationBuilder = new NotificationCompat.Builder(this)
            .SetContentTitle(Header)
            .SetContentText(body)
            .SetSmallIcon(Resource.Mipmap.ic_notification)
            .SetAutoCancel(true)
            .SetContentIntent(pendingIntent);

        var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
        notificationManager.Notify(new Random().Next(), notificationBuilder.Build());
    }
    else
    {
        var notificationBuilder = new NotificationCompat.Builder(this, Utils.CHANNEL_ID)
            .SetContentTitle(Header)
            .SetContentText(body)
            .SetSmallIcon(Resource.Mipmap.ic_notification)
            .SetAutoCancel(true)
            .SetContentIntent(pendingIntent);

        var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
        NotificationChannel channel = new NotificationChannel(Utils.CHANNEL_ID, "FCM Notifications", NotificationImportance.Default);
        notificationManager.CreateNotificationChannel(channel);
        notificationManager.Notify(new Random().Next(), notificationBuilder.Build());
    }
}

2. 通知数据处理逻辑

我参考了官方文档,给MainActivity设置了LaunchMode = LaunchMode.SingleTop,并重写了OnNewIntent方法来处理前台模式的新通知,同时在OnCreate里处理后台/杀死状态的通知:

[Activity(
    // 其他Activity配置项...
    LaunchMode = LaunchMode.SingleTop)]
protected override void OnCreate(Bundle savedInstanceState)
{
    // 初始化代码...
    LoadApplication(new App());

    // 处理后台/杀死状态下启动APP时的通知数据
    CreateNotificationFromIntent(Intent);
}

// 前台模式下收到新通知时,系统会调用这个方法传入新的Intent
protected override void OnNewIntent(Intent intent)
{
    CreateNotificationFromIntent(intent);
}

void CreateNotificationFromIntent(Intent intent)
{
    if (intent.Extras != null)
    {
        foreach (var key in intent.Extras.KeySet())
        {
            var requestData = intent.Extras.GetString("requestData");
            var commentMessageType = intent.Extras.GetString("commentMessageType");
            var revealedLocationName = intent.Extras.GetString("revealedLocationName");
            var revealedLocationId = intent.Extras.GetString("revealedLocationId");

            if (key == "requestData" && !string.IsNullOrEmpty(requestData))
            {
                isNotification = true;
                // 加载带通知数据的App实例
                LoadApplication(new App(requestData, commentMessageType, revealedLocationName, revealedLocationId));
            }
        }
    }
}

问题复现步骤

我做了Demo和Postman集合来复现这个问题,步骤如下:

  1. 把Demo部署到Android设备,获取设备的FCM Token,替换到Postman请求的to字段中。
  2. 保持APP在前台模式,发送名为「Notification 1」的请求,点击通知后,UI正常显示Notification 1的内容。
  3. 继续让APP留在前台,发送名为「Notification 2」的请求,点击通知后,UI仍然显示Notification 1的内容,完全读不到最新的Notification 2数据。
  4. 但如果把APP切到后台,发送新通知并点击,就能正常读取到最新的通知数据,没有任何问题。

我怀疑是Intent里的旧数据没有被清空,但尝试了几种方式都没解决,有没有大佬知道问题出在哪?或者有没有办法在每次处理完通知后,彻底清理Intent里的旧数据,避免下次读取到历史值?

备注:内容来源于stack exchange,提问作者Sreejith Sree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 07:04:28