【问题标题】:Xamarin Forms - Processing a Notification ClickXamarin 表单 - 处理通知单击
【发布时间】:2018-03-18 18:39:15
【问题描述】:

我有一个 Xamarin Forms 应用程序,它会引发 Android 通知,但我无法创建一个简单的页面,当用户单击通知时将与他们进行交互。 我知道在 Xamarin.Forms 中只有 1 个活动,因此挂起的 Intent 必须是该 mainActivity

我已将 LaunchMode 设置为 SingleTop 和 Intent Filter 以匹配在 pendingIntent 中使用的 Intent 名称

现在,当我单击通知时,我确实被路由到 MainActivity 的 OnResume,但我不明白如何: 1)由于单击通知而认识到我在此活动中-我尝试将 Extra 添加到待处理的 Intent 但当我检查 this.Intent.Extras 时它不存在 2)即使我知道我由于点击通知而处于活动中,我如何从活动中启动特定页面。我是 Xamarin 的新手,但看不到如何导航到内容页面或访问导航堆栈。

这一定是一个非常常见的用例,但我找不到任何相关的东西。

【问题讨论】:

    标签: xamarin xamarin.forms notifications xamarin.android local


    【解决方案1】:

    确保您在MainActivity 上设置了LaunchMode.SingleTop

    LaunchMode.SingleTop

    [Activity(~~~, LaunchMode = LaunchMode.SingleTop, ~~~]
    public class MainActivity
    {
       ~~~~
    

    在您的 MainActivity(FormsAppCompatActivity 子类)中添加 OnNewIntent 覆盖:

    OnNewIntent:

    protected override void OnNewIntent(Intent intent)
    {
        base.OnNewIntent(intent);
        NotificationClickedOn(intent);
    }
    

    现在您可以检查intent.Action / intent.HasExtra 以确定是否是您发送的通知并进行处理。使用 Xamarin.Forms 最简单的方法是使用 MessagingCenter 发送在您的 .NetStd/PCL Xamarin.Forms 代码库中订阅的消息。

    NotificationClickedOn:

    void NotificationClickedOn(Intent intent)
    {
        if (intent.Action == "ASushiNotification" && intent.HasExtra("MessageFromSushiHangover"))
        {
            /// Do something now that you know the user clicked on the notification...
    
            var notificationMessage = intent.Extras.GetString("MessageFromSushiHangover");
            var winnerToast = Toast.MakeText(this, $"{notificationMessage}.\n\n? Please send 2 BitCoins to SushiHangover to process your winning ticket! ?", ToastLength.Long);
            winnerToast.SetGravity(Android.Views.GravityFlags.Center, 0, 0);
            winnerToast.Show();
        }
    }
    

    发送通知示例:

    void SendNotifacation()
    {
        var title = "Winner, Winner, Chicken Dinner";
        var message = "You just won a million StackOverflow reputation points";
    
        var intent = new Intent(BaseContext, typeof(MainActivity));
        intent.SetAction("ASushiNotification");
        intent.PutExtra("MessageFromSushiHangover", message);
        var pending = PendingIntent.GetActivity(BaseContext, 0, intent, PendingIntentFlags.CancelCurrent);
    
        using (var notificationManager = NotificationManager.FromContext(BaseContext))
        {
            Notification notification;
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O)
            {
    #pragma warning disable CS0618 // Type or member is obsolete
                notification = new Notification.Builder(BaseContext)
                                                            .SetContentTitle(title)
                                                            .SetContentText(message)
                                                            .SetAutoCancel(true)
                                                            .SetSmallIcon(Resource.Drawable.icon)
                                                            .SetDefaults(NotificationDefaults.All)
                                                            .SetContentIntent(pending)
                                                            .Build();
    #pragma warning restore CS0618 // Type or member is obsolete
            }
            else
            {
                var myUrgentChannel = BaseContext.PackageName;
                const string channelName = "Messages from SushiHangover";
    
                NotificationChannel channel;
                channel = notificationManager.GetNotificationChannel(myUrgentChannel);
                if (channel == null)
                {
                    channel = new NotificationChannel(myUrgentChannel, channelName, NotificationImportance.High);
                    channel.EnableVibration(true);
                    channel.EnableLights(true);
                    channel.SetSound(
                        RingtoneManager.GetDefaultUri(RingtoneType.Notification),
                        new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).Build()
                    );
                    channel.LockscreenVisibility = NotificationVisibility.Public;
                    notificationManager.CreateNotificationChannel(channel);
                }
                channel?.Dispose();
    
                notification = new Notification.Builder(BaseContext)
                                                            .SetChannelId(myUrgentChannel)
                                                            .SetContentTitle(title)
                                                            .SetContentText(message)
                                                            .SetAutoCancel(true)
                                                            .SetSmallIcon(Resource.Drawable.icon)
                                                            .SetContentIntent(pending)
                                                            .Build();
            }
            notificationManager.Notify(1331, notification);
            notification.Dispose();
        }
    }
    

    【讨论】:

    • 感谢您的及时回复。 OnNewIntent 效果很好。
    • 对不起,如果这是一个愚蠢的问题,但是一旦我订阅了一条消息并消费了它,我如何在应用程序中显示一个新页面?我尝试将新页面推送到导航上,但 UI 中没有任何反应 codeMessagingCenter.Subscribe(this, "Hi", (sender) => { Navigation.PushAsync(new UserPage()) ; });
    • @NickJones 你收到消息了吗?即Navigation.PushAsync 是否被调用? Navigation.PushAsync 返回一个任务,你应该在等待它:await Navigation.PushAsync(.....
    • 我在 async 和 await 中添加了我错过的内容,现在我正在调试器中进入内容页面,但视觉上没有发生任何事情。
    • 我找到了一种更简单的方法,似乎可行,只需使用 app.MainPage.Navigation:protected override void OnNewIntent(Intent intent) { base.OnNewIntent(intent); int userMedId = intent.GetIntExtra("userMedId", 0); var action = intent.Action; app.MainPage.Navigation.PushAsync(new ReminderOptions()); }
    猜你喜欢
    • 2019-11-18
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 2021-03-21
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多