Xamarin Android:当我通过通知打开我的应用程序时,启动画面不起作用

Xamarin Android: When I open my application by notification splash-screen doesn't work

如果我通过单击通知(来自 Google Cloud Messaging)打开应用程序,我不会看到启动画面

GcmListenerService.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Gms.Gcm;
using Android.Util;
using System;
using Android.Database.Sqlite;

namespace Dharma.Droid
{
[Service (Exported = false), IntentFilter (new [] { "com.google.android.c2dm.intent.RECEIVE" })]
public class MyGcmListenerService : GcmListenerService
{
    public override void OnMessageReceived (string from, Bundle data)
    {
        var message = data.GetString ("message");
        Log.Debug ("MyGcmListenerService", "From:    " + from);
        Log.Debug ("MyGcmListenerService", "Message: " + message);
        DataAccess.InsertDowload (message);
        SendNotification (message);
    }

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

        var notificationBuilder = new Notification.Builder (this)
            .SetSmallIcon (Resource.Drawable.mhu2)
            .SetContentTitle ("Mobile Health Unit")
            .SetContentText ("U heeft een nieuwe vragenlijst.")
            .SetAutoCancel (true)
            .SetContentIntent (pendingIntent);

        var notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
        notificationManager.Notify (0, notificationBuilder.Build());

    }
}
}

InstanceIdListenerService.cs

using Android.App;
using Android.Content;
using Android.Gms.Gcm.Iid;

namespace Dharma.Droid
{
[Service(Exported = false), IntentFilter(new[] { "com.google.android.gms.iid.InstanceID" })]
class MyInstanceIDListenerService : InstanceIDListenerService
{
    public override void OnTokenRefresh()
    {
        var intent = new Intent (this, typeof (RegistrationIntentService));
        StartService (intent);
    }
}
}

RegistrationIntentService.cs

using System;
using Android.App;
using Android.Content;
using Android.Util;
using Android.Gms.Gcm;
using Android.Gms.Gcm.Iid;

namespace Dharma.Droid
{
[Service(Exported = false)]
class RegistrationIntentService : IntentService
{
    static object locker = new object();

    public RegistrationIntentService() : base("RegistrationIntentService") { }

    protected override void OnHandleIntent (Intent intent)
    {
        try
        {
            Log.Info ("RegistrationIntentService", "Calling InstanceID.GetToken");
            lock (locker)
            {
                var instanceID = InstanceID.GetInstance (this);
                var token = instanceID.GetToken (
                    "***************", GoogleCloudMessaging.InstanceIdScope, null);

                Log.Info ("RegistrationIntentService", "GCM Registration Token: " + token);
                SendRegistrationToAppServer (token);
                Subscribe (token);
            }
        }
        catch (Exception e)
        {
            Log.Debug("RegistrationIntentService", "Failed to get a registration token");
            return;
        }
    }

    void SendRegistrationToAppServer (string token)
    {

    }

    void Subscribe (string token)
    {
        var pubSub = GcmPubSub.GetInstance(this);
        pubSub.Subscribe(token, "/topics/global", null);
    }   
}
}

SplashActivity.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V7.App;
using Android.Util;
using System.Threading.Tasks;
using Android.Gms.Common;

namespace Dharma.Droid
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]      
public class SplashActivity :  AppCompatActivity
{
    static readonly string TAG = "X:" + typeof (SplashActivity).Name;

    public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
    {
        base.OnCreate(savedInstanceState, persistentState);
    }

    protected override void OnResume()
    {
        base.OnResume();

        Task startupWork = new Task(() =>
            {
                Task.Delay(5000); // Simulate a bit of startup work.
            });

        startupWork.ContinueWith(t =>
            {
                NetworkDiscovery network = new NetworkDiscovery();
                CredentialsService cs = new CredentialsService();

                if (GetToken() && network.IsOnline()) 
                {
                    StartActivity(typeof (MainActivity));
                } 
                else
                {
                    StartActivity(typeof (NoInternetActivity)); 
                }

            }, TaskScheduler.FromCurrentSynchronizationContext());

        startupWork.Start();
    }

    public bool GetToken() 
    {
        if (IsPlayServicesAvailable ())
        {
            var intent = new Intent (this, typeof (RegistrationIntentService));
            StartService (intent);
            return true;
        }
        else 
        {
            return false;   
        }
    }

    public bool IsPlayServicesAvailable ()
    {
        int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);

        if (resultCode != ConnectionResult.Success)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}
 }

问题在于这些行:

var intent = new Intent (this, typeof(MainActivity));
intent.AddFlags (ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity (this, 0, intent, PendingIntentFlags.OneShot);

特别是 var intent = new Intent (this, typeof(MainActivity)); 您告诉通知在单击时打开 MainActivity 的位置。如果你想显示启动画面,你应该告诉它打开启动画面,而不是通过将该行替换为:

var intent = new Intent (this, typeof(SplashActivity));

唯一的问题是如果应用程序已经打开,您可能不想再次显示启动画面。要解决这个问题,我建议做一些类似 this 的事情,他们在 IsRunning 上有一个 boolean,它在 MainActivity 生命周期事件中设置。您可以像这样检查 boolean

Activity intent;

if(MainActivity.IsRunning) {
    intent = new Intent (this, typeof(MainActivity));
    intent.AddFlags (ActivityFlags.ClearTop);
} else {
    intent = new Intent (this, typeof(SplashActivity));
    intent.AddFlags (ActivityFlags.ClearTop);
}

var pendingIntent = PendingIntent.GetActivity (this, 0, intent, PendingIntentFlags.OneShot);

警告,我没有测试上面的代码。