Xamarin.Android 应用程序未运行时推送通知正在破坏应用程序 运行

Xamarin.Android push notification is breaking the app when App is Not Running

我正在尝试通过以下方式向我的应用添加推送通知 https://docs.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm

按照此分步教程在 Xamarin.Android 上设置推送通知后,Android 设备会在应用 运行 或后台运行时接收推送通知。但是如果我关闭app让它不再是运行,然后发送推送通知,设备会显示这个 错误信息:

“Unfortunately, [App Name] has stopped”

这是我的代码实现..

[Service] // Must use the service tag
public class PushHandlerService : GcmServiceBase
{
    public static string RegistrationID { get; private set; }
    private NotificationHub Hub { get; set; }

    public PushHandlerService() : base(Constants.SenderID)
    {
        Log.Info(MyBroadcastReceiver.TAG, "PushHandlerService() constructor");
    }

    protected override void OnRegistered(Context context, string registrationId)
    {
        Log.Verbose(MyBroadcastReceiver.TAG, "GCM Registered: " + registrationId);
        RegistrationID = registrationId;

        /*createNotification("PushHandlerService-GCM Registered...",
                            "The device has been Registered!");*/

        Hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString,
                                    context);
        try
        {
            Hub.UnregisterAll(registrationId);
        }
        catch (Exception ex)
        {
            Log.Error(MyBroadcastReceiver.TAG, ex.Message);
        }

        //var tags = new List<string>() { "falcons" }; // create tags if you want
        var tags = new List<string>() { };

        try
        {
            var hubRegistration = Hub.Register(registrationId, tags.ToArray());
        }
        catch (Exception ex)
        {
            Log.Error(MyBroadcastReceiver.TAG, ex.Message);
        }
    }
    protected override void OnMessage(Context context, Intent intent)
    {
        Log.Info(MyBroadcastReceiver.TAG, "GCM Message Received!");

        var msg = new System.Text.StringBuilder();

        if (intent != null && intent.Extras != null)
        {
            foreach (var key in intent.Extras.KeySet())
                msg.AppendLine(key + "=" + intent.Extras.Get(key).ToString());
        }

        string messageText = intent.Extras.GetString("message");
        if (!string.IsNullOrEmpty(messageText))
        {
            createNotification("New hub message!", messageText);
        }
        else
        {
            createNotification("Unknown message details", msg.ToString());
        }
    }
    void createNotification(string title, string desc)
    {
        //Create notification
        var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;

        //Create an intent to show UI
        var uiIntent = new Intent(this, typeof(MainActivity));

        //Create the notification
        var notification = new Notification(Android.Resource.Drawable.SymActionEmail, title);

        //Auto-cancel will remove the notification once the user touches it
        notification.Flags = NotificationFlags.AutoCancel;

        //Set the notification info
        //we use the pending intent, passing our ui intent over, which will get called
        //when the notification is tapped.
        notification.SetLatestEventInfo(this, title, desc, PendingIntent.GetActivity(this, 0, uiIntent, 0));

        //Show the notification
        notificationManager.Notify(1, notification);
        dialogNotify(title, desc);
    }

    protected void dialogNotify(string title, string message)
    {
        MainActivity.instance.RunOnUiThread(() => {
            AlertDialog.Builder dlg = new AlertDialog.Builder(MainActivity.instance);
            AlertDialog alert = dlg.Create();
            alert.SetTitle(title);
            alert.SetButton("Ok", delegate {
                alert.Dismiss();
            });
            alert.SetMessage(message);
            alert.Show();
        });
    }

    protected override void OnUnRegistered(Context context, string registrationId)
    {
        Log.Verbose(MyBroadcastReceiver.TAG, "GCM Unregistered: " + registrationId);

        createNotification("GCM Unregistered...", "The device has been unregistered!");
    }

    protected override bool OnRecoverableError(Context context, string errorId)
    {
        Log.Warn(MyBroadcastReceiver.TAG, "Recoverable Error: " + errorId);

        return base.OnRecoverableError(context, errorId);
    }

    protected override void OnError(Context context, string errorId)
    {
        Log.Error(MyBroadcastReceiver.TAG, "GCM Error: " + errorId);
    }
}

}`

最后我通过对 OnMessage

方法进行异步处理来解决问题

代码如下:

    protected override async void OnMessage(Context context, Intent intent)
    {
    Log.Info(MyBroadcastReceiver.TAG, "GCM Message Received!");
        await Task.Delay(1000);

        var msg = new System.Text.StringBuilder();
        if (intent != null && intent.Extras != null)
        {
            foreach (var key in intent.Extras.KeySet())
                msg.AppendLine(key + "=" + intent.Extras.Get(key).ToString());
        }

        string messageText = intent.Extras.GetString("message");
        if (!string.IsNullOrEmpty(messageText))
        {
           createNotification("New hub message!", messageText);
        }
        else
        {
           createNotification("Unknown message details", msg.ToString());
        }
    }`