从android通知加载Xamarin Forms页面

时间:2017-07-06 12:13:45

标签: xamarin.android xamarin.forms

我正在尝试从Android通知加载Xamarin表单页面。我真的迷失在这方面的机器人方面,我的大部分代码都是从教程和博客文章中拼凑而成的。但是,似乎没有什么能真正涵盖这种情况。

我已经使用依赖服务实现了一个非常简单的接口,以创建具有intent ...的通知。

[assembly: Xamarin.Forms.Dependency(typeof(QuoteNotification))]

namespace QuoteApp.Droid
{

    class QuoteNotification : IQuoteNotification
    {


        public void Notify(string title, string message)
        {

            //type needs to be derived from java, not xamarin.forms
            Intent LoadPostPage = new Intent(Forms.Context, typeof(DroidToForms));
            const int pendingIntentId = 0;
            PendingIntent pendingIntent =
                PendingIntent.GetActivity(Forms.Context, pendingIntentId, LoadPostPage, PendingIntentFlags.OneShot);

            Notification.Builder builder = new Notification.Builder(Forms.Context)
                .SetContentIntent(pendingIntent)
                .SetAutoCancel(true)

                     .SetContentTitle(title)
                     .SetContentText(message)
                     .SetSmallIcon(Resource.Drawable.icon);

            // Build the notification:
            Notification notification = builder.Build();

            // Get the notification manager:
            NotificationManager notificationManager =
                Forms.Context.GetSystemService(Context.NotificationService) as NotificationManager;

            // Publish the notification:
            const int notificationId = 0;
            notificationManager.Notify(notificationId, notification);
        }
    }
}

这称为活动 -

namespace QuoteApp.Droid
{
    [Activity(Label = "QuoteApp", MainLauncher = true)]
    class DroidToForms : Activity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            StartActivity(typeof(XFPostPage));
            //Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());

        }
    }
}

反过来调用这个表单页面,这里的所有代码都在Xamarin.Android项目中

namespace QuoteApp.Droid
{



        /// <summary>
        /// This is a Xamarin.Forms screen. It MUST:
        /// * inherit from ANdroidActivity
        /// * call Forms.Init()
        /// * use LoadApplication()
        /// </summary>
        [Activity(Label = "XFPostPage", MainLauncher = true) ]
        public class XFPostPage : Xamarin.Forms.Platform.Android.FormsApplicationActivity
        {
            protected override void OnCreate(Bundle bundle)
            {
                base.OnCreate(bundle);

                Xamarin.Forms.Forms.Init(this, bundle);

            //LoadApplication( new App() ); //how do i send to PostPage.xaml ??

            Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());
        }
        }
    }

这在logcat中给出了以下错误

07-04 17:51:44.494  7668  7668 E AndroidRuntime: Caused by: android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object
07-04 17:51:44.494  7668  7668 E AndroidRuntime:   at QuoteApp.Droid.XFPostPage.OnCreate (Android.OS.Bundle bundle) [0x00016] in <ab64801c0fb24acb8457c1d1202cc143>:0
07-04 17:51:44.494  7668  7668 E AndroidRuntime:   at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <d855bac285f44dda8a0d8510b679b1e2>:0
07-04 17:51:44.494  7668  7668 E AndroidRuntime:   at (wrapper dynamic-method) System.Object:2780fa42-5931-40d3-8d14-a642f1a3025c (intptr,intptr,intptr)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at md543d03747be5a5b03a21a2a23b8ba191a.XFPostPage.n_onCreate(Native Method)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at md543d03747be5a5b03a21a2a23b8ba191a.XFPostPage.onCreate(XFPostPage.java:29)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:6237)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.ActivityThread.-wrap11(ActivityThread.java)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:102)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:148)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:5417)
07-04 17:51:44.494  7668  7668 E AndroidRuntime:        ... 3 more

我尝试了许多不同的想法都有不同的运行时错误,我对Xamarin.Android工作的理解非常有限。最终我将使用AlarmManager的通知,更多信息将发送到PostPage.Xaml。目前我只是迷失在这个错误的地方虽然?!

任何帮助将非常感谢,提前感谢。

2 个答案:

答案 0 :(得分:2)

对于任何偶然发现此问题的人,我最终在OnNewIntent中使用了MainActivity

这里有一些很好的信息Processing notifications in Xamarin Forms Android

我的代码最终看起来像这样。

调用依赖服务来获取android implmentation

DependencyService.Get<IQuoteNotification>().Notify("words",SelectedQuote.FixedTitle  , SelectedQuote.Id);

使用Intent构建通知:

  class QuoteNotification : IQuoteNotification
    {


        public void Notify(string title, string message, int postIndex)
        {

            //type needs to be derived from java, not xamarin.forms
            Intent LoadPostPage = new Intent(Forms.Context, typeof(MainActivity));
            LoadPostPage.PutExtra("NotificationTrue", true);
            LoadPostPage.PutExtra("PostID", postIndex);
            const int pendingIntentId = 0;
            PendingIntent pendingIntent =
                PendingIntent.GetActivity(Forms.Context, pendingIntentId, LoadPostPage, PendingIntentFlags.OneShot);


            Notification.Builder builder = new Notification.Builder(Forms.Context)
                    .SetContentIntent(pendingIntent)
                    .SetAutoCancel(true)
                    .SetContentTitle(title)
                    .SetContentText(message)
                    .SetSmallIcon(Resource.Drawable.icon);

            // Build the notification:
            Notification notification = builder.Build();

            // Get the notification manager:
            NotificationManager notificationManager =
                Forms.Context.GetSystemService(Context.NotificationService) as NotificationManager;

            // Publish the notification:
            const int notificationId = 0;
            notificationManager.Notify(notificationId, notification);
        }
    }

然后在OnNewIntent中覆盖MainActivity。如果意图不是由我的QuoteNotification类构建,则发送-1作为PostID

        protected override void OnNewIntent(Intent intent)
    {
        if (intent.HasExtra("NotificationTrue")){
            LoadApplication(new App(intent.GetIntExtra("PostID", -1)));
            //Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new QuoteApp.PostPage());
        }
        base.OnNewIntent(intent);
    }

然后在App.Xaml.cs中添加一些逻辑以导航到正确的页面

public partial class App : Application
{
    public App(int PostId = -1)
    {
        InitializeComponent();

        if (PostId >= 0)
        {
            MainPage = new NavigationPage(new PostPage(PostId));
        }
        else
            MainPage = new NavigationPage(new MainPage());

谢谢,希望它有所帮助。

答案 1 :(得分:1)

问题在于您的代码Intent LoadPostPage = new Intent(Forms.Context, typeof(DroidToForms));

对于XF项目的Android平台,它只有一个Activity,即MainActivity,或者基于此MainActivity呈现XF页面。

所以你可以改变你这样的代码:

Intent intent = new Intent(context, typeof(MainActivity));
intent.PutExtras(valuesForActivity);

PendingIntent resultPendingIntent = PendingIntent.GetActivity(Xamarin.Forms.Forms.Context, 0, intent, PendingIntentFlags.OneShot);

然后使用OnCreate MainActivity方法:

//navigate to the page of PCL
Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new PostPage());

最后,正如@Pratik建议的那样,如果您要为Android平台创建原生页面/视图,请使用PageRendererViewRenderer来执行此操作。