【问题标题】:Xamarin.Forms Firebasepushnotification plugin OnNotificationOpened event causes app to restart for androidXamarin.Forms Firebasepushnotification 插件 OnNotificationOpened 事件导致应用程序为 android 重新启动
【发布时间】:2021-09-15 12:04:18
【问题描述】:

我正在尝试通过使用“Plugin.FirebasePushNotification”插件并订阅“OnNotificationOpened”事件来处理我通过 Google 的 FCM 在 SharedProject 级别发送的在 Android 上打开的通知。

当我在应用程序处于后台时尝试打开通知时,我能够在“OnNotificationOpened”事件内打断点,但在事件内的工作结束 App const 之后。被击中,应用程序重新启动。

我希望应用程序从上一个状态继续并点击位于 App 类中的“OnResume”方法。

我在网上做了一些关于它的研究,几乎所有的研究都是关于启动活动如何导致这个问题,所以我通过将整个“SplashActivity.cs”文件转换为除命名空间之外的注释来禁用启动活动和用法并在“MainActivity”类中实现了所需的splashactivity(style)功能,之后我确保我的“MainActivity”类是唯一将“MainLauncher”属性设置为true但问题仍然存在的活动。

以下是相关类:

FirebaseReg.cs

public class FirebaseReg
    {
        public static void FirebaseInit()
        {
            CrossFirebasePushNotification.Current.OnTokenRefresh += (s, p) =>
            {
                System.Diagnostics.Debug.WriteLine($"TOKEN : {p.Token}");
                CrossFirebasePushNotification.Current.Subscribe("defaultTopic");
            };

            CrossFirebasePushNotification.Current.OnNotificationOpened += (s, p) =>
            {
                try
                {
                    //Breakpoint hits here and I'm able to finish all my work without any exceptions 
                }
                catch (Exception ex)
                {

                }
            };

            CrossFirebasePushNotification.Current.OnNotificationAction += (s, p) =>
            {
            };

            CrossFirebasePushNotification.Current.OnNotificationReceived += Current_OnNotificationReceived;
        }

        private static void Current_OnNotificationReceived(object source, FirebasePushNotificationDataEventArgs e)
        {
            //DO WORK
        }

}

App.xaml.cs

public partial class App : Application
{
    public static Uri ServerUri = new Uri(" ");
    public static bool IsInForeground { get; set; } = false;

    public App()
    {
        try
        {
            InitializeComponent(); //After the work in OnNotificationOpened ends breakpoint goes here
            Application.Current.UserAppTheme = OSAppTheme.Unspecified;
            
            Application.Current.MainPage = new LoginPage();
        }
        catch (Exception ex)
        {
           
        }

    }

    protected override void OnStart()
    {
        IsInForeground = true;
    }

    protected override void OnSleep()
    {
        IsInForeground = false;
    }

    protected override void OnResume()
    {
        IsInForeground = true;
    }

}

MainActivity.cs

[Activity(Label = "TestProject1", Theme = "@style/MyTheme.Splash", 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.Window.RequestFeature(WindowFeatures.ActionBar);
            // Name of the MainActivity theme you had there before.
            // Or you can use global::Android.Resource.Style.ThemeHoloLight
            base.SetTheme(Resource.Style.MainTheme);


            base.OnCreate(savedInstanceState);

            Rg.Plugins.Popup.Popup.Init(this);
            UserDialogs.Init(this);

            Xamarin.FormsGoogleMaps.Init(this, savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            FirebasePushNotificationManager.ProcessIntent(this ,Intent);
            LoadApplication(new App());
        }
        protected override void OnNewIntent(Intent intent)
        {
            FirebasePushNotificationManager.ProcessIntent(this, intent);
            base.OnNewIntent(intent);
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

MainApplication.cs

 [Application]
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
    public MainApplication(IntPtr handle, JniHandleOwnership transer) : base(handle, transer)
    {

    }

    public override void OnCreate()
    {
        base.OnCreate();

        RegisterActivityLifecycleCallbacks(this);

        if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            FirebasePushNotificationManager.DefaultNotificationChannelId = "DefaultChannel";
            FirebasePushNotificationManager.DefaultNotificationChannelName = "defaultTopic";
        }


#if DEBUG
            FirebasePushNotificationManager.Initialize(this, true);
            FirebaseRegister.FirebaseInit();
#else
            FirebasePushNotificationManager.Initialize(this, false);
            FirebaseRegister.FirebaseInit();
#endif
    }

    public override void OnTerminate()
    {
        base.OnTerminate();
        UnregisterActivityLifecycleCallbacks(this);
    }

    public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivityDestroyed(Activity activity)
    {
    }

    public void OnActivityPaused(Activity activity)
    {
    }

    public void OnActivityResumed(Activity activity)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
    {
    }

    public void OnActivityStarted(Activity activity)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivityStopped(Activity activity)
    {
    }


}

【问题讨论】:

  • but after the work inside the event ends the App const. is hit and the application restarts.上面的话是什么意思? App const 是什么?另外,我也不太明白这句话:I want the application to continue from its last state and hit "OnResume" method that is located inside the App class.。你能详细解释一下吗?
  • @JessieZhang-MSFT “应用程序常量。”是位于“App.xaml.cs”文件中的 App 构造函数,当我说我希望应用程序从其上一个状态继续时,我的意思是当我单击通知时我不希望应用程序重新启动.如果应用程序已经存在于后台,我只想让 android 从上一个状态继续我的应用程序并点击“OnResume”方法,当您点击发送到后台的应用程序时,同样的影响适用于它点击“OnResume”当我单击我的通知时,我希望应用相同的效果。如果应用已经在后台

标签: c# android xamarin.forms plugins firebase-cloud-messaging


【解决方案1】:

来自Android docs,它指出:

如果它已将其启动模式声明为“多重”(默认)并且 您没有以相同的意图设置 FLAG_ACTIVITY_SINGLE_TOP,那么它 将完成并重新创建;对于所有其他启动模式,或者如果 设置了 FLAG_ACTIVITY_SINGLE_TOP 然后这个 Intent 将被传递到 当前实例的 onNewIntent()。

这就是您的应用重新启动的原因。

活动的launchMode 属性会影响活动的启动方式。

应使用singleTopsingleTasksingleInstance 来防止通知意图创建新的活动实例。

标志FLAG_ACTIVITY_NEW_TASK 不会影响正在创建的新活动,但会使启动的活动成为新任务的根。

更多信息,请查看:

https://developer.android.com/guide/topics/manifest/activity-element.html#lmode

https://developer.android.com/guide/components/activities/tasks-and-back-stack

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2019-02-19
    • 2013-09-02
    • 1970-01-01
    相关资源
    最近更新 更多