如何在Xamarin.forms

时间:2017-03-22 15:47:31

标签: xamarin push-notification xamarin.forms

我目前正在开发适用于iOS和Android的Xamarin应用程序,但我要解释的问题仅涉及Android应用程序(这尚未在iOS应用程序中实现)。 / p>

实际上,当我收到给定的推送通知时,我需要在我的应用程序中打开一个特定的页面。如果在收到推送通知时应用程序处于打开状态,它的效果非常好,但如果我的应用程序已关闭或在后台运行,应用程序将崩溃。

好吧,当我收到通知时,我最终会使用名为" OnShouldOpenCommand" :

  private void OnShouldOpenCommand(string commandId)
        {
            NotifyNewCommand(AppResources.AppName, AppResources.CommandNotificationText, commandId);

            Device.BeginInvokeOnMainThread(() =>
            {
                try
                {

                    App.MasterDetailPage.Detail = new NavigationPage(new CommandAcceptancePage(commandId))
                    {
                        BarBackgroundColor = Color.FromHex("1e1d1d")
                    };

                    App.MasterDetailPage.NavigationStack.Push(((NavigationPage)(App.MasterDetailPage.Detail)).CurrentPage);
                }
                catch(Exception e)
                {                   
                        Log.Debug("PushAsync", "Unable to push CommandAcceptancePage : "+ex.Message);
                }

            });
        }

    private void NotifyNewCommand(string Title,string Description, string commandId)
    {
        var intent = new Intent(this, typeof(MainActivity));
        if (!String.IsNullOrEmpty(commandId))
        {
            intent.PutExtra("CommandId", commandId);
        }
        intent.AddFlags(ActivityFlags.ClearTop);
        var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);

        var notificationBuilder = new Notification.Builder(this)
            .SetSmallIcon(Resource.Drawable.icon)
            .SetContentTitle("Kluox")
            .SetContentText(Description)
            .SetAutoCancel(true)
            .SetContentIntent(pendingIntent);

        Notification notification = notificationBuilder.Build();

        var notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
        notificationManager.Notify(0, notification);
    }

代码

App.MasterDetailPage.Detail = new NavigationPage(new CommandAcceptancePage(commandId))
                    {
                        BarBackgroundColor = Color.FromHex("1e1d1d")
                    };

正在生成类型的异常:

  

Java.Lang.IllegalStateException:之后无法执行此操作   的onSaveInstanceState

好吧,我想我无法访问" App"如果我的应用程序未在前台运行,则重定向到另一个页面。好吧,这是当我收到推送通知而不是我点击它时。但是,我不打算通过这样做重新打开我的应用程序。

因为当我点击名为Kluox的推送通知(这应该重新打开我的应用程序)时,应用程序崩溃,我真的不知道为什么,我不知道在哪里将断点设置为能够调试,因为Visual Studio只是告诉我"发生了未处理的异常。"。

enter image description here

有人能帮帮我吗?如果您需要任何代码,您可以问我,我会编辑我的消息并为您提供所需的任何信息!

编辑1:以下是我的OnCreate方法的代码:

protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);
            var info = Intent.Extras?.GetString("CommandId", "");
            global::Xamarin.Forms.Forms.Init(this, bundle);
            if (String.IsNullOrEmpty(info))
            {
                LoadApplication(new App());
            }
            else
            {
                LoadApplication(new App(info));
            }
            if (instance == null)
            {
                instance = this;
                RegisterWithGCM();
            }
            else
            {
                instance = this;
            }
        }

2 个答案:

答案 0 :(得分:2)

好吧,幸运的是,我几天前在那里,失去了很多头发,直到我在Android上工作(并且仍然在iOS版本中)。

当您终止应用并再次从图标或通知中实例化时,您将转到主要活动。

如果我们想从实例化通知的主要活动中获取一些信息,我们会在 OnCreate() 中这样做:

var info = Intent.Extras?.GetString("info", "");

现在,在您的情况下,我会在通知中添加额外信息,以显示此通知所关注的视图/页面,例如其名称等。

这些额外的信息可以在加载之前传递给App的构造函数。

在应用程序的构造函数中,您可以检查是否有额外的信息,如果不是这意味着启动应用程序的mainPage是默认的MainPage,否则它是某个页面。

答案 1 :(得分:2)

在覆盖 MainActivity 的所有方法之后,我终于找到了崩溃的原因:OnDestroy方法被调用了两次,并抛出了IllegalStateException,因为活动已被销毁。我发现了这个解决方法:

 protected override void OnDestroy()
        {
            try
            {
                base.OnDestroy();
            }
            catch (Java.Lang.IllegalStateException ex)
            {
                Log.Debug("MainActivity.OnDestroy", ex, "The activity was destroyed twice");
            }

        }

只是记录了异常,应用程序可以打开并可以毫无问题地使用。

我也会在重定向工作时编辑这个答案。

编辑:如何重定向到网页

首先,我们需要在构造函数

中注册MessagingCenter
public static MyPackage.Model.Command CurrentCommand { get; set; }
public App()
{
    InitializeComponent();
    MainPage = new ContentPage();
    MessagingCenter.Subscribe<object, DataLib.Model.Command>(this, "Command", (sender, arg) => {
      try
      {
         CurrentCommand = arg;
      }
      catch(Exception ex)
      {
         CurrentCommand = null;
      }
    });
  }

当我们收到推送通知时发送消息:

private void OnMessage(string serializedCommand)
{
  //stuff happens
  MessagingCenter.Send<object, MyPackage.Model.Command>(this, "Command", command);
}

最后,当我们得到App.Xaml.cs的OnStart()

                if (CurrentCommand != null)
                {
                    App.MasterDetailPage.Detail = new NavigationPage(new CommandAcceptancePage(CurrentCommand, service))
                    {
                        BarBackgroundColor = Color.FromHex("1e1d1d")
                    };
                }

目前,它似乎已经成功了!接下来会有更多调试,但代码似乎有效。非常感谢@BraveHeart的帮助!