【问题标题】:Xamarin.Forms Android app hangs when opened by tapping push message通过点击推送消息打开 Xamarin.Forms Android 应用程序时挂起
【发布时间】:2019-03-20 09:32:18
【问题描述】:

我有一个使用 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 属性可以解决问题,但我不太明白,为什么...

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

【问题讨论】:

  • stackoverflow.com/q/50795697/2232127 的可能重复项。您需要提供更多信息。你是如何发送消息的?
  • 解析整数时似乎出错,请发布您的完整代码
  • 我可以看看你的相关代码,也许我可以为你指出一些事情
  • 感谢所有努力,我用相关代码更新了我的问题
  • innomotion 媒体的回答可以参考。也许通知来的时候你的应用程序正在运行。**SingleTask** 是尝试使活动单一,然后当你打开应用程序时不会发生重复活动导致冲突。所以它也可以解决你的问题。

标签: android firebase xamarin firebase-cloud-messaging


【解决方案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());
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多