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
相关产品推荐
相关产品推荐

