关闭应用程序后 GCM 通知使应用程序崩溃

GCM Notification crashes app after I close the app

当我的应用程序 运行(在前台和后台)时,我可以接收通知,并使用 Android 的 NotificationManager 向用户显示通知。但是,在将应用程序从最近的应用程序中滑开后,当应用程序收到通知时,我收到消息 Unfortunately, MyApp has stopped working.

我知道应用从最近的消息中滑开后应该可以收到通知,因为我已经设置了百度通知,我可以在应用滑开后接收通知。但是对于 GCM,它只会导致应用程序崩溃。这是有问题的代码:

[BroadcastReceiver(Name = "com.my.pkg.MyGcmReceiver", Exported = true, Permission = "com.google.android.c2dm.permission.SEND")]
[IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "com.my.pkg" })]
public class MyGcmReceiver : GcmReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        base.OnReceive(context, intent);
        System.Diagnostics.Debug.WriteLine("MyGcmReceiver - OnReceive called &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
        CreateNotification();
    }

    private void CreateNotification()
    {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(Xamarin.Forms.Forms.Context);

        builder.SetAutoCancel(true);
        builder.SetDefaults(NotificationCompat.DefaultAll);
        builder.SetSmallIcon(Resource.Drawable.icon);
        builder.SetContentTitle("HI");
        builder.SetContentText("MSG FROM GCM");
        builder.SetPriority((int)NotificationPriority.Max);

        NotificationManager manager = (NotificationManager)Xamarin.Forms.Forms.Context.GetSystemService(Context.NotificationService);

        manager.Notify(0, builder.Build());
    }
}

通过注释掉 OnReceive 方法中的 CreateNotification(); 行,应用程序不会崩溃,但当然不会创建和显示通知。

正如我在评论中所说,使用 FCM 似乎容易得多,因为它负责处理消息。

我正在使用 Visual Studio 2017 和 Xamarin Forms 版本 2.3.224(它也应该适用于 2.3.3.193)。我还在我的解决方案中附上了 Nuget 包的屏幕截图。我将 Xamarin.Firebase.Messaging 添加到 Android 项目而不是表单项目。

对于 运行 FCM,您必须创建一个帐户并下载 google-services.json 文件。关于此的更多信息 here

为了在 Xamarin Forms 中实现这一点,我在 Android 中创建了 2 个服务, 1 依赖服务 2 个意图服务。

依赖服务只检查 PlayService 是否可用并获取 FirebaseToken。

    public class PlayServices: IPlayService
{
    public string IsPlayServicesAvailable()
    {
        int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(Forms.Context);
        if (resultCode != ConnectionResult.Success)
        {
            if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
                return GoogleApiAvailability.Instance.GetErrorString(resultCode);
            return "This device is not supported";
        }
        return "Available";
    }

    public string FirebaseToken => FirebaseInstanceId.Instance.Token;
}

现在,w.r.t。意图服务

    [Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIidService : FirebaseInstanceIdService
{
    const string TAG = "MyFirebaseIIDService";
    public override void OnTokenRefresh()
    {
        var refreshedToken = FirebaseInstanceId.Instance.Token;
        Log.Debug(TAG, "Refreshed token: " + refreshedToken);
        SendRegistrationToServer(refreshedToken);
    }
    void SendRegistrationToServer(string token)
    {
        // Add custom implementation, as needed.
    }

}

这将在应用程序启动后立即 运行,并且通常在应用程序启动后大约 6-7 秒内完成。这会从 Firebase 生成一个令牌并将其提供给应用程序。

虽然您不需要令牌(因为您可以向所有安装了您的应用程序的手机发送推送消息),但您可以使用它仅向 Phone 发送推送通知。

希望对您有所帮助