推送通知上的应用程序重新加载单击 Xamarin 表单

Posted

技术标签:

【中文标题】推送通知上的应用程序重新加载单击 Xamarin 表单【英文标题】:App Reload on Push Notification Click Xamarin Forms 【发布时间】:2017-06-28 14:30:03 【问题描述】:

我已经在我的应用程序上实现了推送通知,它们运行良好。 我遇到的问题是,当我在下拉菜单中单击它们时,它们会立即重新加载应用程序。为了解决这个问题,我让应用程序创建了一个新的活动实例。现在这会打开一个新页面,但是当从这个新页面返回时,它会遇到同样的问题并重新加载整个应用程序。

我将 Xamarin Forms 与 PCL 一起使用,因此它不是纯 android。 有没有办法让菜单项上的点击事件在 PCL 中加载特定的页面视图?重新加载整个应用程序是没有用的。

这是创建电话通知的类:

ForegroundMessages.cs:

 [Service]
[IntentFilter(new[]  "com.google.firebase.MESSAGING_EVENT" )]

public class ForegroundMessages: FirebaseMessagingService



    const string TAG = "MyFirebaseMsgService";
    public override void OnMessageReceived(RemoteMessage message)
    
        //Log.Debug(TAG, "From: " + message.From);
        //Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
        base.OnMessageReceived(message);
        SendNotification(message.GetNotification().Body);
    

    private void SendNotification(string body)
    
        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.ClearTop);
       // var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

        Log.Debug(TAG, "Notification Message Body: " + body);

        // sends notification to view model
        MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "Increase");

        Intent resultintent = new Intent(this,typeof(SecondActivity));

        TaskStackBuilder stackbuilder = TaskStackBuilder.Create(this);
        stackbuilder.AddParentStack(Java.Lang.Class.FromType(typeof(SecondActivity)));
        stackbuilder.AddNextIntent(resultintent);

        PendingIntent resultPendingIntent = stackbuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);

        var defaultSoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
        var notificationBuilder = new NotificationCompat.Builder(this)
            .SetSmallIcon(Resource.Drawable.icon)
            .SetContentTitle("Notification")
            .SetContentText(body)
            .SetAutoCancel(true)
            .SetSound(defaultSoundUri)
            .SetContentIntent(resultPendingIntent);

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
    



和第二个Activity类:

  [Activity(Label = "Notifications")]
public class SecondActivity:Activity


    protected override void OnCreate(Bundle bundle)
    
        base.OnCreate(bundle);

        System.Diagnostics.Debug.WriteLine("this worked");
    


如上所述,这可以正常工作并接收消息,当您单击它们时,它会加载第二个活动,但是当离开第二个活动页面时,它只会重新加载整个应用程序。 如果我可以在 PCL 中加载视图页面(.xaml 或 .xaml.cs)而不是这个,那会更好。

有什么想法吗?

【问题讨论】:

所以我知道它为什么会重新加载整个应用程序。默认情况下,它会创建一个新的主要活动实例,因此会重新加载整个事情。所以我打算使用第二个活动作为中介来加载一个 xaml 页面。我会告诉你进展如何。 【参考方案1】:

您可以查看my post,它显示了我是如何做到的,我还打开了一个表单页面。这篇文章有点长,但基本上有几件事:

我不使用第二个Activity 我没有将ClearTop 标志添加到MainActivity Intent 我不使用TaskStackBuilder 而只是使用PendingIntent.GetActivity 来获取PendingIntent 然后我通过将您的MainActivityLaunchMode 设置为LaunchMode.SingleTop,覆盖MainActivity 中的OnNewIntent,然后检查intent.HasExtras 的特殊您在 SendNotification 方法中设置的 string 以将 Intent 与其他 Intent 区分开来

如果您之后仍有问题,请告诉我。

编辑:

private void SendNotification(string body)

    var intent = new Intent(this, typeof(MainActivity));
    intent.AddFlags(ActivityFlags.ClearTop);
   // var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
    intent.PutExtra("SomeSpecialKey", "some special value");

    Log.Debug(TAG, "Notification Message Body: " + body);

    if (Forms.IsInitialized)  // Ensure XF code has been initialized
        // sends notification to view model
        MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "Increase");
    

    PendingIntent pendingIntent = PendingIntent.GetActivity(Application.Context, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.OneShot);

    var defaultSoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
    var notificationBuilder = new NotificationCompat.Builder(this)
        .SetSmallIcon(Resource.Drawable.icon)
        .SetContentTitle("Notification")
        .SetContentText(body)
        .SetAutoCancel(true)
        .SetSound(defaultSoundUri)
        .SetContentIntent(pendingIntent);

    var notificationManager = NotificationManager.FromContext(this);
    notificationManager.Notify(0, notificationBuilder.Build());

然后在MainActivity中:

[Activity(LaunchMode = LaunchMode.SingleTop, ....)]
public class MainActivity : FormsApplicationActivity 

    protected override void OnNewIntent(Intent intent) 
        if(intent.HasExtra("SomeSpecialKey")) 
            System.Diagnostics.Debug.WriteLine("\nIn MainActivity.OnNewIntent() - Intent Extras: " + intent.GetStringExtra("SomeSpecialKey") + "\n");
        

        base.OnNewIntent(intent);
    

【讨论】:

谢谢。对我来说这是一天的结束,但我明天第一件事会检查这个。 @user3355961 听起来不错。我会注意到我使用的是旧的 GCM API,而不是新的 Firebase API,但我认为本地 Android 通知 API 不会受此影响。 嗨,我已经让我在主要活动中达到超车意图,但我不确定如何通过它intent.HasExtra。我在发送通知中设置什么来触发 HasExtra 条件? 当我在 Main Activity 中放置一个断点时,意图显示为具有 null extras @user3355961 正确。在您的 SendNotification 方法中,您不会向您的 MainActivity Intent 添加任何额外内容。所以尝试添加intent.PutExtra("some special key", "some special value"); 然后你会在OnNewIntent 中寻找"some special key"【参考方案2】:

只需将LaunchMode = LaunchMode.SingleTask 添加到您的 MainActivity

【讨论】:

以上是关于推送通知上的应用程序重新加载单击 Xamarin 表单的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Android 如何使“wav”文件成为应用程序的默认推送通知声音?

Xamarin.iOS 中的 Azure 推送通知不起作用

Xamarin iOS - 推送通知 - 区分点击的推送通知与到达

推送通知未到达

如何注册展会推送通知设备

Xamarin和推送通知 - 使用Azure通知中心的原因?