Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

App Reload on Push Notification Click Xamarin Forms

I have implemented push notifications on my app and they work fine. The problem I have is that when I click them in the pull down menu they immediately reload the app. To counter this I had the app create a new activity instance. This now opens a new page but when clicking back from this new page it has the same problem and reloads the whole app again.

I am using Xamarin Forms with PCL, so its not pure Android. Is there a way to get the click event on the menu item to load a specific page view in PCL? Reloading the whole app is kind of useless.

This is the class the creates the phone notification:

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());
    }


}

and the Second Activity class:

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

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

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

}

As stated, this works and receives messages fine and when you click them it loads second activity but when moving away from the second activity page it just reloads the whole app again. It would be better if I could load a view page (.xaml or .xaml.cs) in the PCL rather than this.

Any ideas?

like image 744
user3355961 Avatar asked Jun 28 '17 14:06

user3355961


2 Answers

You might check out my post which shows how I did it, I also open a Forms page. The post is kind of long but basically there are a few things:

  • I do not use a second Activity
  • I do not add the ClearTop flag to the MainActivity Intent
  • I do not use the TaskStackBuilder and instead just use PendingIntent.GetActivity to get the PendingIntent
  • Then I specifically address the app restart issue in the post by setting your MainActivity's LaunchMode to LaunchMode.SingleTop, overriding OnNewIntent in your MainActivity, and then checking the intent.HasExtras for a special string that you set in your SendNotification method to distinguish that Intent from some other Intent

Let me know if you still have problems afterwards.

Edit:

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());
}

Then in 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);
    }
like image 113
hvaughan3 Avatar answered Oct 11 '22 18:10

hvaughan3


Just add LaunchMode = LaunchMode.SingleTask to your MainActivity

like image 20
Nick Kovalsky Avatar answered Oct 11 '22 20:10

Nick Kovalsky