Xamarin.Forms Android应用在通过点击推送消息打开时会挂起

时间:2019-03-20 09:32:19

标签: android firebase xamarin firebase-cloud-messaging

我有一个用Xamarin Android开发的Android应用。

工作正常,但我有一个烦人的错误:通过从Android顶部栏中点击推送消息(通过Firebase消息)启动应用程序时,该应用程序会启动,但会挂在黑屏状态。

我有以下异常信息:

03-20 10:24:02.907 W/FirebaseMessaging( 9068): Error while parsing timestamp in GCM event
03-20 10:24:02.907 W/FirebaseMessaging( 9068): java.lang.NumberFormatException: s == null
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at java.lang.Integer.parseInt(Integer.java:570)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at java.lang.Integer.valueOf(Integer.java:794)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.messaging.zzd.zzb(Unknown Source:60)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.messaging.zzd.zzh(Unknown Source:84)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.messaging.FirebaseMessagingService.zzo(Unknown Source:35)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.iid.zzf.zza(Unknown Source:38)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.iid.zzh.zzcfv(Unknown Source:80)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.iid.zzh.zza(Unknown Source:29)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.google.firebase.iid.FirebaseInstanceIdInternalReceiver.onReceive(Unknown Source:41)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:3392)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.app.ActivityThread.-wrap18(Unknown Source:0)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1780)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.os.Handler.dispatchMessage(Handler.java:105)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.os.Looper.loop(Looper.java:164)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at android.app.ActivityThread.main(ActivityThread.java:6944)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at java.lang.reflect.Method.invoke(Native Method)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
03-20 10:24:02.907 W/FirebaseMessaging( 9068):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
03-20 10:24:02.908 W/FirebaseMessaging( 9068): Unable to log event: analytics library is missing
**03-20 10:24:02.939 E/BpSurfaceComposerClient( 9068): Failed to transact (-1)
03-20 10:24:02.940 D/SurfaceView( 9068): BG destroy() Surface(name=Background for - SurfaceView - com.xy.z/md5042a29578a9bda3ea52b7f93956e5082.MainActivity@f4c217c@1) android.opengl.GLSurfaceView{f4c217c V.E...... ........ 0,0-1080,1596}
03-20 10:24:02.940 E/BpSurfaceComposerClient( 9068): Failed to transact (-1)**
Thread finished: <Thread Pool> #6
The thread 0x6 has exited with code 0 (0x0).
Thread finished: <Thread Pool> #20
Thread started: <Thread Pool> #21
The thread 0x14 has exited with code 0 (0x0).
Thread finished: <Thread Pool> #10
The thread 0xa has exited with code 0 (0x0).

更新:FireBaseMessagingService代码:

[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
    public override void OnMessageReceived(RemoteMessage message)
    {
        SendNotification(message.GetNotification().Body, message.Data);
    }

    void SendNotification(string messageBody, IDictionary<string, string> data)
    {
         var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.ClearTop);
        foreach (var key in data.Keys)
        {
            intent.PutExtra(key, data[key]);
        }

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

        var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
                                  .SetSmallIcon(Resource.Drawable.Icon)
                                  .SetContentTitle("XYZ")
                                  .SetContentText(messageBody)
                                  .SetAutoCancel(true)
                                  .SetContentIntent(pendingIntent);

        var notificationManager = NotificationManagerCompat.From(this);
        notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
    }
}

这是从服务器发送通知的代码:

public override bool Send(string deviceToken, string message)
    {
        try
        {
            var serverKey = string.Format("key={0}", "xy");
            var senderId = string.Format("id={0}", "11111111");

            var data = new
            {
                to = deviceToken,
                priority = "high",
                notification = new
                {
                    title = "XYZ",
                    body = message,
                    sound = "enabled"
                }
            };

            var jsonData = JsonConvert.SerializeObject(data);
            var byteArray = Encoding.UTF8.GetBytes(jsonData);

            var req = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
            req.Method = "post";
            req.ContentType = "application/json";

            req.Headers.Add(string.Format("Authorization: {0}", serverKey));
            req.Headers.Add(string.Format("Sender: {0}", senderId));

            using (var dataStream = req.GetRequestStream())
            {
                dataStream.Write(byteArray, 0, byteArray.Length);
                using (var response = req.GetResponse())
                {
                    using (var dataStreamResponse = response.GetResponseStream())
                    {
                        using (var streamReader = new StreamReader(dataStreamResponse))
                        {
                            var responseFromServer = streamReader.ReadToEnd();
                        }
                    }
                }
            }

            return true;
        }
        catch (Exception exc)
        {
            Logger.Error(exc.Message);
            Debug.Assert(false, exc.Message);
            return false;
        }
    }

更新2: 看来在MainActivity中添加LaunchMode = LaunchMode.SingleTask,ClearTaskOnLaunch = true属性可以解决问题,但我不完全了解,为什么...

您有什么建议吗?非常感谢!

1 个答案:

答案 0 :(得分:1)

首先检查android操作系统开始推送:

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            SetOreoNotification();
        }
        else
        {
            DispatchNotificationThatServiceIsRunning();
        }

然后执行此操作(摘自我的一个在所有Android设备上均可正常运行的项目:)

 void DispatchNotificationThatServiceIsRunning()
        {
            int id = 50;
            try
            {
                RemoteViews contentView = new RemoteViews(PackageName, Resource.Layout.Notification);
                contentView.SetTextViewText(Resource.Id.txt_crrentSong_notification, Activity_Player.txt_CurrentSong.Text);
                contentView.SetTextViewText(Resource.Id.txt_crrentSong__artist_notification, Activity_Player.txt_CurrentArtist.Text);

                notificationBuilder = new Notification.Builder(ApplicationContext);

                Notification.Builder builder = new Notification.Builder(this)
                .SetSmallIcon(Resource.Drawable.btn_icon_header)
                .SetCustomContentView(contentView);

                Task.Delay(_countDownFirstRound).ContinueWith(t =>
                {
                    NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
                    notificationManager.Notify(id, notificationBuilder.Build());

                    DispatchNotificationThatServiceIsRunning();//This is for repeate every 1s.

                    _countDownFirstRound = 50;

                    // Click on notification, and return to app. Only works, because _2TimerRunning is set as : "LaunchMode = LaunchMode.SingleInstance"
                    Intent notificationIntent = new Intent(this, typeof(Activity_Player));
                    notificationIntent.SetAction(Intent.ActionMain);
                    notificationIntent.AddCategory(Intent.CategoryLauncher);
                    PendingIntent contentIntent = PendingIntent.GetActivity(this, 1, notificationIntent, PendingIntentFlags.UpdateCurrent);
                    notificationBuilder.SetContentIntent(contentIntent);

                },

                TaskScheduler.FromCurrentSynchronizationContext());
            }
            catch
            {
                Toast.MakeText(this, "ERROR NOTIFY", ToastLength.Short).Show();
            }
        }

        void SetOreoNotification()
        {
            RemoteViews contentView = new RemoteViews(PackageName, Resource.Layout.NotificationOreo);
            contentView.SetTextViewText(Resource.Id.txt_crrentSong_notification_oreo, Activity_Player.txt_CurrentSong.Text);
            contentView.SetTextViewText(Resource.Id.txt_crrentSong__artist_notification_oreo, Activity_Player.txt_CurrentArtist.Text);

            const string URGENT_CHANNEL = "com.xamarin.myapp.urgent";
            string chanName = "xy";
            var importance = NotificationImportance.Default;
            NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, chanName, importance);

            chan.SetSound(null, null);

            //chan.EnableVibration(true);

            chan.LockscreenVisibility = NotificationVisibility.Private;

            NotificationManager notificationManager =
            (NotificationManager)GetSystemService(NotificationService);
            notificationManager.CreateNotificationChannel(chan);

            Intent notificationIntent = new Intent(this, typeof(Activity_Player));
            notificationIntent.SetAction(Intent.ActionMain);
            notificationIntent.AddCategory(Intent.CategoryLauncher);
            PendingIntent contentIntent = PendingIntent.GetActivity(this, 1, notificationIntent, PendingIntentFlags.UpdateCurrent);

            Notification.Builder builder = new Notification.Builder(this)
            .SetSmallIcon(Resource.Drawable.btn_icon_header)
            .SetCustomContentView(contentView)
            .SetChannelId(URGENT_CHANNEL)
            .SetContentIntent(contentIntent)
            .SetGroupAlertBehavior(NotificationGroupAlertBehavior.Summary)
            .SetGroup("My group")
            .SetGroupSummary(false);

             const int NOTIFY_ID = 1100;
             notificationManager.Notify(NOTIFY_ID, builder.Build());
        }