推送通知使用有效负载打开正确的页面

Posted

技术标签:

【中文标题】推送通知使用有效负载打开正确的页面【英文标题】:Push Notification use payload to open correct page 【发布时间】:2014-12-26 13:09:23 【问题描述】:

首先,我将 Xamarin Forms 用于 WP8、iosandroid 应用程序。

目标:

我想在点击 toast 时转到特定页面,具体取决于 根据 toast 通知的有效负载信息。

我有使用 Azure 通知中心的推送通知,所有设置都运行良好。我使用 MVVMLight 及其依赖注入专门为每个平台设置推送通知。

由于所需的格式不同,每个有效载荷都需要发送一些不同的内容。对于每一个,您都会注意到我想在有效负载中发送一个 SignalId,以便根据常规推送通知在接收设备上执行不同的操作。

安卓


  "data" : 
    "msg" : "message in here",
    "signalId" : "id-in-here",
  ,

iOS



    "aps" :  "alert" : "message in here" ,
    "signalId" : "id-in-here"


Windows Phone 8

 <?xml version="1.0" encoding="utf-8"?>
 <wp:Notification xmlns:wp="WPNotification">
     <wp:Toast>
          <wp:Text1>category</wp:Text1>
          <wp:Text2>message in here</wp:Text2>
          <wp:Param>?signalId=id-in-here</wp:Param>
     </wp:Toast>
 </wp:Notification>

.

问题:

如何在 Xamarin Forms 应用程序中获取此信息并重定向到 重新激活应用程序时的相应页面,因为 用户点击了 toast 通知?

我想在应用加载时获取有效负载信息,然后说,是的,它包含一个 SignalId,让我们重定向到此页面。

目前,它会在单击 toast 通知时显示应用程序。我必须针对应用程序执行此操作,还是有 Xamarin Forms 方式?

任何帮助,即使你只知道如何在一个平台上做,我也可以从那里绕过其他平台。

【问题讨论】:

【参考方案1】:

我已经找到了适用于所有平台的方法。 Windows 已经过测试,Android 和 iOS 还没有。

如果应用程序在后台,Windows 和 iOS 会处理显示 toast 通知,或者如果应用程序在前台,则让您的代码处理它。无论应用程序状态如何,Android 都会显示 toast。

对于 Windows Phone 8,我需要转到 MainPage.xaml.cs 并添加此覆盖。

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    
        base.OnNavigatedTo(e);

        if (this.NavigationContext.QueryString.ContainsKey("signalId"))
        
            var signalId = this.NavigationContext.QueryString["signalId"];
            var id = Guid.Empty;

            if (signalId != null
                && Guid.TryParse(signalId, out id)
                && id != Guid.Empty)
            
                this.NavigationContext.QueryString.Clear();
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                
                    // Do my navigation to a new page
                );
            
        
    

在 GcmService 中适用于 Android

  protected override void OnMessage(Context context, Intent intent)
        
            Log.Info(Tag, "GCM Message Received!");

            var message = intent.Extras.Get("msg").ToString();
            var signalId = Guid.Empty;

            if (intent.Extras.ContainsKey("signalId"))
            
                signalId = new Guid(intent.Extras.Get("signalId").ToString());
            


                // Show notification as usual
                CreateNotification("", message, signalId);


        

然后在 CreateNotification 函数中将一些额外的信息放入 Intent 中。

            var uiIntent = new Intent(this, typeof(MainActivity));

            if (signalId != Guid.Empty)
            
                uiIntent.PutExtra("SignalId", signalId.ToString());
            

然后在MainActivity.cs中重写这个函数

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    
        if (data.HasExtra("SignalId"))
        
            Guid signalId = new Guid(data.GetStringExtra("SignalId"));
            if (signalId != Guid.Empty)
            
                data.RemoveExtra("SignalId");
                // Do you navigation
            
        
    

在 iOS 中你会注意到我增强了默认的 ProcessNotification()

  void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
    
        // Check to see if the dictionary has the aps key.  This is the notification payload you would have sent
        if (null != options && options.ContainsKey(new NSString("aps")))
        
            //Get the aps dictionary
            var aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;

            var alert = string.Empty;

            //Extract the alert text
            // NOTE: If you're using the simple alert by just specifying 
            // "  aps:alert:"alert msg here"  " this will work fine.
            // But if you're using a complex alert with Localization keys, etc., 
            // your "alert" object from the aps dictionary will be another NSDictionary. 
            // Basically the json gets dumped right into a NSDictionary, 
            // so keep that in mind.
            if (aps.ContainsKey(new NSString("alert")))
                alert = ((NSString) aps[new NSString("alert")]).ToString();

            // If this came from the ReceivedRemoteNotification while the app was running,
            // we of course need to manually process things like the sound, badge, and alert.
            if (!fromFinishedLaunching)
            
                //Manually show an alert
                if (!string.IsNullOrEmpty(alert))
                
                    var signalId = new Guid(options.ObjectForKey(new NSString("signalId")) as NSString);

                    // Show my own toast with the signalId
                
            
        
    

然后在 FinishedLaunching 函数中检查是否有任何有效载荷

        // Check if any payload from the push notification
        if (options.ContainsKey("signalId"))
        
            var signalId = new Guid(options.ObjectForKey(new NSString("signalId")) as NSString);

            // Do the navigation here         
        

【讨论】:

在安卓解决方案上。导航到特定页面的语法是什么样的?

以上是关于推送通知使用有效负载打开正确的页面的主要内容,如果未能解决你的问题,请参考以下文章

推送通知有效负载未保存在某些设备上

如何编写使用推送通知有效负载启动应用程序的UI测试,并验证您是否已路由到正确的视图?

修改 UNNotificationService 扩展中推送通知有效负载中的“声音”属性

反正有保存推送通知吗?

Android GCM:通知关闭后重复推送

服务总线通知中心:推送通知的有效负载大小限制是多少?