【问题标题】:Firebase notification click Intent show null on Background state - Xamarin.forms AndroidFirebase 通知单击 Intent 在背景状态上显示 null - Xamarin.forms Android
【发布时间】:2020-11-19 21:38:37
【问题描述】:

在我的 xamarin.forms 应用程序中,我使用了 Firebase 推送通知。在 android 部分,我可以在Foreground ,background and killed state 上收到通知。我面临的问题是当我在后台状态或终止状态下点击通知时,我无法从Intent 获取值;它显示为空。这之前工作得很好,我不知道我做错了什么。当应用程序处于前台模式时,我可以获得通知的值。

我的 FirebaseMessagingService

[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService

{
    // private string TAG = "MyFirebaseMsgService";
    public static string EmployeeID = "";
    public static string StartDate = "";
    public static string NotificationType = "";
    public static string TotalHours = "";
    public static string EmployeeName = "";
    public static string EmployeeNumber = "";
    public override void OnMessageReceived(RemoteMessage message)
    {
        base.OnMessageReceived(message);
        try
        {
            SendNotification(message.GetNotification().Body, message.GetNotification().Title, message.Data);
            EmployeeID = message.Data["EmpID"].ToString();
            StartDate = message.Data["SDate"].ToString();
            NotificationType = message.Data["NotificationType"].ToString();
            TotalHours = message.Data["TotalHours"].ToString();
            EmployeeName = message.Data["EmployeeName"].ToString();
            EmployeeNumber = message.Data["EmpNo"].ToString();
        }

        catch (Exception ex)
        {
        }

    }
    private void SendNotification(string messageBody, string messageTitle, IDictionary<string, string> data)
    {

        var intent = new Intent(this, typeof(MainActivity));
        intent.PutExtra("user_notification_id", EmployeeID);

        intent.AddFlags(ActivityFlags.ClearTop);
        foreach (var key in data.Keys)
        {
            intent.PutExtra(key, data[key]);
        }
        var pendingIntent = PendingIntent.GetActivity(this, new Random().Next(), intent, PendingIntentFlags.OneShot);
        var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID).SetSmallIcon(Resource.Drawable.icon_logo).SetContentTitle(messageTitle).SetContentText(messageBody).SetAutoCancel(true).SetContentIntent(pendingIntent).SetVibrate(new long[] { 1000, 1000 }).SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)).SetStyle((new NotificationCompat.BigTextStyle().BigText(messageBody)));
        var notificationManager = NotificationManagerCompat.From(this); notificationManager.Notify(new Random().Next(), notificationBuilder.Build());

    }

}

主要活动

namespace App.Droid
{
    [Activity(Label = "App", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = false ]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        static readonly string TAG = "MainActivity";
        internal static readonly string CHANNEL_ID = "my_notification_channel";
        internal static readonly int NOTIFICATION_ID = 100;
        private bool isNotification = false;

        protected override void OnCreate(Bundle savedInstanceState)
        {    
            IsPlayServicesAvailable(); //You can use this method to check if play services are available.
            CreateNotificationChannel();// Notification channel is required for Android 8.0 + to receive notifications.        
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);                              
            
            // Here Iam getting Intent values as null on background or killed state
            
                if (Intent.Extras != null)
                {
                    foreach (var key in Intent.Extras.KeySet())
                    {
                        if (key != null)
                        {
                            var value = Intent.Extras.GetString(key);
                            string EmployeeID = Intent.Extras.GetString("EmpID");
                            string startDate = Intent.Extras.GetString("SDate");
                            string NotificationType = Intent.Extras.GetString("NotificationType");
                            string EmployeeName = Intent.Extras.GetString("EmployeeName");
                            string TotalHours = Intent.Extras.GetString("TotalHours");
                            string EmpNo = Intent.Extras.GetString("EmpNo");
                            LoadApplication(new App(true, EmployeeID, startDate, NotificationType, EmployeeName, TotalHours, EmpNo));
                        }
                    }
                }
                else
                {                 LoadApplication(new App(isNotification));
                }
                
        }

        // <-------------- Notification click management in foregorund mode--->
        protected override void OnNewIntent(Intent intent)
        {
            if (intent != null)
            {
                var message = intent.GetStringExtra("EmpID");
                if (!string.IsNullOrEmpty(message))
                {
                    string EmployeeID = intent.GetStringExtra("EmpID");
                    string startDate = intent.GetStringExtra("SDate");
                    string NotificationType = intent.GetStringExtra("NotificationType");
                    string EmployeeName = intent.GetStringExtra("EmployeeName");
                    string TotalHours = intent.GetStringExtra("TotalHours");
                    string EmpNo = intent.GetStringExtra("EmpNo");
                    LoadApplication(new App(true, EmployeeID, startDate, NotificationType, EmployeeName, TotalHours, EmpNo));
                }
            }
            base.OnNewIntent(intent);
        }

        //<-------------- Checking whether google play service is availabe for fcm-------------------->
        public bool IsPlayServicesAvailable()
        {
            int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this); if (resultCode != ConnectionResult.Success)
            {
                if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
                {

                }
                // msgText.Text = GoogleApiAvailability.Instance.GetErrorString(resultCode);
                else
                {
                    //This device is not supported           
                    Finish(); // Kill the activity if you want.         
                }
                return false;
            }
            else
            {
                //Google Play Services is available.         
                return true;
            }
        }

        void CreateNotificationChannel()
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.O)
            {
                // Notification channels are new in API 26 (and not a part of the
                // support library). There is no need to create a notification 
                // channel on older versions of Android.
                return;
            }

            var channel = new NotificationChannel(CHANNEL_ID, "FCM Notifications", NotificationImportance.High)
            {
                Description = "Firebase Cloud Messages appear in this channel",
            };
            channel.EnableVibration(true);
            channel.EnableLights(true);
            channel.LockscreenVisibility = NotificationVisibility.Public;
            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.CreateNotificationChannel(channel);
        }

    }
}

我正在使用 Xamarin.forms 版本 4.6.0.800 和 Xamarin.Firebase.Messaging 版本 71.1740.4。任何帮助表示赞赏

编辑

问题与我的 SplashScreen 有关。当我删除 SplashActivty 并为 MainActivity 设置 MainLauncher 为 True 时,问题解决了。即使 App 关闭,我也可以获得 Intent 值。那么如何解决 Splashscreen 的问题?我应该将 Intent 从 SplashActivity 传递给 MainActivty 吗?

我的SplashActivity

[Activity(Label = "App", MainLauncher = true,
  LaunchMode = LaunchMode.SingleTop,
  ScreenOrientation = ScreenOrientation.Portrait,
  Theme = "@style/splashscreen", NoHistory = true)]
    public class SplashActivity : AppCompatActivity

    {

        static readonly string TAG = "X:" + typeof(SplashActivity).Name;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
            {
                Window.DecorView.SystemUiVisibility = StatusBarVisibility.Visible;
                Window.SetStatusBarColor(Android.Graphics.Color.Transparent);
            }

            InvokeMainActivity();
        }

        private void InvokeMainActivity()
        {
            var mainActivityIntent = new Intent(this, typeof(MainActivity));
            mainActivityIntent.AddFlags(ActivityFlags.NoAnimation); //Add this line
            StartActivity(mainActivityIntent);
        }

    }

【问题讨论】:

    标签: firebase xamarin xamarin.forms xamarin.android


    【解决方案1】:

    首先,您需要在 Firebase 有效负载中设置 "click_action":"OPEN_ACTIVITY_1"。

    然后使用 IntentFilterAttribute 标记您的默认活动

    [IntentFilter(new[] { "OPEN_ACTIVITY_1" }, Categories = new[] { "android.intent.category.DEFAULT" })]
    

    如果没有 click_action,您的通知不知道要启动哪个活动。

    注意:OPEN_ACTIVITY_1这个值可以改变,但是需要注意的是Firebase和IntentFilter之间的这个值必须相同。

    【讨论】:

    • 我之前在 Notification 有效负载中没有 click_action 属性,它已经工作了,请问还有其他原因吗?
    • 感谢您的指导。根据firebase通知文档“如果必须触发不同的Intent,则必须将通知消息的click_action字段设置为该Intent(未指定click_action时使用启动器Intent)。”所以我的疑问是,如果我们不使用任何特定的 click_action,Intent.GetExtra 是否会为空?
    【解决方案2】:

    对于这个愚蠢的问题,抱歉。问题是每当我单击通知时,Intent 都会传递给 SplashActivity。我没有将 Intent 从 Splash 传递到 Main Activity。感谢@Cahyo 的帮助。

    我在SplashActivity添加了这个

     private void InvokeMainActivity()
            {
                var mainActivityIntent = new Intent(this, typeof(MainActivity));
                if (Intent.Extras != null)
                {
                    mainActivityIntent.PutExtras(Intent.Extras);
                }
                mainActivityIntent.AddFlags(ActivityFlags.NoAnimation); //Add this line
                StartActivity(mainActivityIntent);
            } 
    

    【讨论】:

      猜你喜欢
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多