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

Xamarin.Forms中如何处理用户点击本地通知的事件

Xamarin.Forms 本地通知点击跳转及逻辑处理完整方案

以下是全平台可运行的实现方案,覆盖冷启动、后台运行两种场景下的通知点击事件处理:


整体实现逻辑

  • 本地通知创建时附带自定义业务参数(如跳转页面标识、业务ID等)存入通知额外字段
  • 原生平台监听通知点击事件,取出参数后传递到Xamarin.Forms共享层
  • 共享层统一接收参数,执行对应业务逻辑

1. 共享层代码实现

首先定义全局处理的接口和逻辑:

// 通知业务参数模型
public class LocalNotification
{
    public string Title { get; set; }
    public string Body { get; set; }
    // 自定义参数存储字段,可根据业务需求扩展
    public Dictionary<string, string> CustomData { get; set; } = new();
}

在App.xaml.cs中实现全局通知处理逻辑:

public partial class App : Application
{
    // 存储冷启动场景下的待处理通知参数
    public static Dictionary<string, string> PendingNotificationData { get; set; }

    public App()
    {
        InitializeComponent();
        MainPage = new AppShell();
    }

    protected override void OnStart()
    {
        // 冷启动完成后处理待处理的通知参数
        if (PendingNotificationData != null)
        {
            ProcessNotificationData(PendingNotificationData);
            PendingNotificationData = null;
        }
    }

    // 统一处理所有通知点击的业务逻辑
    public void ProcessNotificationData(Dictionary<string, string> data)
    {
        if (data == null || !data.Any()) return;
        // 示例逻辑:根据参数跳转对应页面
        if (data.TryGetValue("TargetPage", out var targetPage))
        {
            switch (targetPage)
            {
                case "MessageDetail":
                    if (data.TryGetValue("MessageId", out var msgId))
                    {
                        MainPage.Navigation.PushAsync(new MessageDetailPage(msgId));
                    }
                    break;
                // 可根据业务需求扩展其他逻辑
            }
        }
    }
}

2. Android端实现

2.1 通知创建时携带参数

在Android项目的通知服务实现中,构建通知时把自定义参数存入PendingIntent:

private void ShowLocalNotification(LocalNotification notification)
{
    var intent = new Intent(Platform.CurrentActivity, typeof(MainActivity));
    // 存入所有自定义参数
    foreach (var (key, value) in notification.CustomData)
    {
        intent.PutExtra(key, value);
    }
    intent.AddFlags(ActivityFlags.SingleTop | ActivityFlags.ClearTop);

    var pendingIntent = PendingIntent.GetActivity(
        Platform.CurrentActivity,
        new Random().Next(),
        intent,
        PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable);

    // 基础通知构建逻辑省略,仅保留核心参数
    var notificationBuilder = new NotificationCompat.Builder(Platform.CurrentActivity, "YOUR_CHANNEL_ID")
        .SetContentTitle(notification.Title)
        .SetContentText(notification.Body)
        .SetSmallIcon(Resource.Drawable.ic_notification)
        .SetContentIntent(pendingIntent)
        .SetAutoCancel(true);

    var notificationManager = NotificationManager.FromContext(Android.App.Application.Context);
    notificationManager.Notify(new Random().Next(), notificationBuilder.Build());
}

2.2 MainActivity接收通知点击事件

[Activity(Label = "YourAppName", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        // 冷启动时处理Intent携带的通知参数
        ProcessNotificationIntent(Intent);

        LoadApplication(new App());
    }

    // 应用在后台时点击通知触发该方法
    protected override void OnNewIntent(Intent intent)
    {
        base.OnNewIntent(intent);
        ProcessNotificationIntent(intent);
    }

    private void ProcessNotificationIntent(Intent intent)
    {
        if (intent.Extras == null) return;
        var notificationData = new Dictionary<string, string>();
        foreach (var key in intent.Extras.KeySet())
        {
            notificationData.Add(key, intent.Extras.GetString(key));
        }
        if (notificationData.Any())
        {
            if (Xamarin.Forms.Application.Current is App app)
            {
                // 应用已启动直接处理逻辑
                app.ProcessNotificationData(notificationData);
            }
            else
            {
                // 应用未启动存入待处理队列
                App.PendingNotificationData = notificationData;
            }
        }
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

3. iOS端实现

3.1 通知创建时携带参数

在iOS项目的通知服务实现中,将自定义参数存入UserInfo:

private void ShowLocalNotification(LocalNotification notification)
{
    var content = new UNMutableNotificationContent();
    content.Title = notification.Title;
    content.Body = notification.Body;
    content.Sound = UNNotificationSound.Default;
    // 存入自定义参数
    var userInfo = new NSMutableDictionary();
    foreach (var (key, value) in notification.CustomData)
    {
        userInfo.Add(new NSString(key), new NSString(value));
    }
    content.UserInfo = userInfo;

    var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(0.1, false);
    var request = UNNotificationRequest.FromIdentifier(Guid.NewGuid().ToString(), content, trigger);
    UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
    {
        if (err != null)
        {
            // 处理通知创建异常
        }
    });
}

3.2 AppDelegate接收通知点击事件

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        Xamarin.Essentials.Platform.Init();

        // 请求通知权限
        UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound, (approved, error) =>
        {
            // 处理权限请求结果
        });
        UNUserNotificationCenter.Current.Delegate = new NotificationDelegate();

        // 冷启动时处理通知参数
        if (options != null && options.ContainsKey(UIApplication.LaunchOptionsLocalNotificationKey))
        {
            if (options[UIApplication.LaunchOptionsLocalNotificationKey] is UILocalNotification localNotif)
            {
                ProcessNotificationUserInfo(localNotif.UserInfo);
            }
        }

        LoadApplication(new App());
        return base.FinishedLaunching(app, options);
    }

    // 统一处理通知参数
    public void ProcessNotificationUserInfo(NSDictionary userInfo)
    {
        if (userInfo == null) return;
        var notificationData = new Dictionary<string, string>();
        foreach (var item in userInfo)
        {
            if (item.Key is NSString key && item.Value is NSString value)
            {
                notificationData.Add(key.ToString(), value.ToString());
            }
        }
        if (notificationData.Any())
        {
            if (Xamarin.Forms.Application.Current is App app)
            {
                app.ProcessNotificationData(notificationData);
            }
            else
            {
                App.PendingNotificationData = notificationData;
            }
        }
    }
}

// 通知代理实现
public class NotificationDelegate : UNUserNotificationCenterDelegate
{
    // 应用前台收到通知时的展示逻辑
    public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
    {
        completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound);
    }

    // 点击通知时触发
    public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
    {
        var userInfo = response.Notification.Request.Content.UserInfo;
        if (UIApplication.SharedApplication.Delegate is AppDelegate appDelegate)
        {
            appDelegate.ProcessNotificationUserInfo(userInfo);
        }
        completionHandler();
    }
}

适配注意事项

  • Android 12及以上版本需要声明android.permission.POST_NOTIFICATIONS权限,且PendingIntent必须指定Immutable或Mutable标识
  • 自定义参数仅存储业务标识类轻量数据,避免超出系统限制导致数据丢失
  • 低于iOS 10的系统版本需要适配UILocalNotification对应的旧API

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:27:03