【问题标题】:How to deeplink a Firebase Messaging background notification?如何深度链接 Firebase 消息传递后台通知?
【发布时间】:2021-05-14 04:40:03
【问题描述】:

对于 Xamarin.Android,当关闭的应用收到通知时,它会触发 HandleIntent()。我想在打开后台通知后指定目标(意图)页面,例如在应用已打开时收到前台通知时。

如何在 HandleIntent() 中指定意图页面以深层链接到应用程序的不同部分,而不是打开应用程序主页的后台通知?或者有没有办法 OnResume() 应用程序并捕获 Message.Data 值然后深层链接到另一个页面?

using System;
using Android.App;
using Android.Content;
using Android.Media;

using Android.Support.V4.App;
using Firebase.Messaging;

namespace Appname
{
    [Service(Name = "com.mydomainname.appname.MyFirebaseMessagingService")]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
        const string TAG = "MyFirebaseMsgService";
        internal static readonly string CHANNEL_ID = "alerts_channel";

        public override void OnNewToken(string token)
        {
            base.OnNewToken(token);
        }

        public override void OnMessageReceived(RemoteMessage message)
        {
            if (message.Data.Count > 0)
            {
                // NOTIFICTION AS DATA WITH ID
                Android.Util.Log.Debug(TAG, "From: " + message.From);
                Android.Util.Log.Debug(TAG, "Title: " + message.GetNotification().Title);
                Android.Util.Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
                Android.Util.Log.Debug(TAG, "Data: " + message.Data["EId"]);
                SendNotification(message.GetNotification().Title, message.GetNotification().Body, message.Data["EId"]);
            }
            else
            {
                // NOTIFICATION WITHOUT DATA
                Android.Util.Log.Debug(TAG, "From: " + message.From);
                Android.Util.Log.Debug(TAG, "Title: " + message.GetNotification().Title);
                Android.Util.Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
                SendNotification(message.GetNotification().Title, message.GetNotification().Body, null);
            }
        }

        public override void HandleIntent(Intent intent)// this method will fire when the app in background/closed state, and the foreground before calling OnMessageReceived()
        {
            base.HandleIntent(intent);
            string strTitle = "";
            string strBody = "";
            string strEId = "";

            if (intent.Extras != null)
            {
                foreach (var key in intent.Extras.KeySet())
                {
                    var value = intent.Extras.GetString(key);
                    switch (key)
                    {
                        case "gcm.notification.title":
                            strTitle = value;
                            break;
                        case "gcm.notification.body":
                            strBody = value;
                            break;
                        case "EId":
                            strEId = value;
                            break;
                    }
                }
            }
        }

        void SendNotification(string messageTitle, string messageBody, string strEId)
        {
            Intent intent;
            if(strEId == null)
            {
                intent = new Intent(this, typeof(MainActivity));
            }
            else
            {
                intent = new Intent(this, typeof(pageEvent));
                intent.PutExtra("EID", strEId);
            }

            intent.AddFlags(ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity(this, 0 /* Request code */, intent, PendingIntentFlags.OneShot);

            var defaultSoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
            var notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .SetSmallIcon(Resource.Mipmap.ic_launcher_round)
                .SetContentTitle(messageTitle)
                .SetContentText(messageBody)
                .SetAutoCancel(true)
                .SetSound(defaultSoundUri)
                .SetContentIntent(pendingIntent);

            var notificationManager = NotificationManager.FromContext(this);

            notificationManager.Notify(0 /* ID of notification */, notificationBuilder.Build());
        }
    }
}

【问题讨论】:

  • 我对这个细节不是很熟悉,但我想到了两个(模糊的)想法:1)在 HandleIntent 中,是否有一些“内部”通知或 MessageCenter 消息可以触发,即那么应用程序会收到吗? 2)如果您在某处设置了一些“静态”值,应用程序会在执行 OnResume 时看到它吗?底线:找到某种方式来传达信息,应用程序可以在 OnResume 中使用,或在 OnResume 之后不久使用。 (棘手的部分是找到一种机制,它可以在 onResume 发生之前执行一些不会被清除/重新初始化的操作。)
  • 遵循此响应/示例应该会引导您了解您正在尝试做的事情stackoverflow.com/questions/25787908/…

标签: xamarin xamarin.forms xamarin.android firebase-cloud-messaging android-notifications


【解决方案1】:

在 sendNotification 函数中,如果您根据代码查看下面的意图创建,您将看到指定了要打开的活动的名称。

    if(strEId == null)
    {
        intent = new Intent(this, typeof(MainActivity));
    }
    else
    {
        intent = new Intent(this, typeof(pageEvent));
        intent.PutExtra("EID", strEId);
    }

当 strEId == null 时打开主屏幕,即。主要活动 否则打开指定打开的页面。即 pageEvent(它可以是您想要的任何活动)。

所以你需要做的是指定当某些通知到达时你需要打开到意图中的活动。

在这里,您有多个选项可以选择如何深度链接到您所需的屏幕。

  1. 您可以在现有代码中指定活动来代替 pageEvent 或根据任何其他条件创建新意图等。

intent = new Intent(this, typeof(pageEvent));, ,其中 pageEvent 可以是任何活动名称

  1. 您可以将通知类型与通知数据一起发送。 然后根据通知类型,您可以指定需要打开的活动类型以及需要传递给该活动的数据(如果有)。

      void SendNotification(string messageTitle, string messageBody, string strEId,string notifType)
                 {
    
       Intent intent;
    
       switch (notifType) 
       {
         case "home":
           //create intent for home page
           break;
         case "customPage":
           //create intent for customPage
           break;    
     }
    
     now pass the intent to pendingIntent and show the notification.
    

    }

  2. 您可以在将通知类型传递给主屏幕意图时从通知转到主屏幕。然后在主屏幕中创建一个自定义函数来处理通知。它将检查 Intent 中是否有任何通知类型,如果存在则我们从主屏幕重定向到目标屏幕。

【讨论】:

    猜你喜欢
    • 2020-12-12
    • 2022-06-20
    • 2021-02-19
    • 2017-02-06
    • 1970-01-01
    • 2020-10-27
    • 2018-03-16
    • 2016-12-25
    • 2020-07-28
    相关资源
    最近更新 更多