Xamarin Forms - 处理通知点击

Xamarin Forms - Processing a Notification Click

我有一个 Xamarin Forms 应用程序,它会引发 Android 通知,但我在创建一个简单的页面时遇到了问题,该页面将在用户单击通知时与用户交互。 我知道在 Xamarin.Forms 中只有 1 个 activity,因此待处理的 Intent 必须指向那个 mainActivity

我已将 LaunchMode 设置为 SingleTop,并将 Intent Filter 设置为与 pendingIntent 中使用的 Intent 名称相匹配

现在,当我单击通知时,我确实会转到 MainActivity 的 OnResume,但我不知道如何: 1) 认识到我在这个 activity 中是因为通知点击 - 我尝试向未决 Intent 添加一个 Extra 但当我检查 this.Intent.Extras 时它不存在 2) 即使我知道由于通知点击我在 activity 中,我如何从 Activity 启动特定页面。我是 Xamarin 的新手,但看不到如何导航到内容页面或访问导航堆栈。

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

确保您已在 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 Whosebug 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();
    }
}