【问题标题】:Notification received sent via FCM in xamarin.forms but image is not displayed in system tray通过 FCM 在 xamarin.forms 中收到通知,但图像未显示在系统托盘中
【发布时间】:2020-05-14 18:36:14
【问题描述】:

我在 FCM 上设置了一个应用程序,以在 Xamarin.Forms 中向 android 设备发送通知,但只收到通知,但系统托盘中不显示图像。

这是我的 AndroidManifest.xml

<application android:label="DMSMobileApp.Android">
    <receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
    android:exported="false" />
    <receiver
        android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
      <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="${applicationId}" />
      </intent-filter>
    </receiver>
  </application>

我创建了 FirebaseMessagingService.cs 来接收并转换为本地通知。

[Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
        const string TAG = "MyFirebaseMsgService";
        public override void OnMessageReceived(RemoteMessage message)
        {
            var body = message.GetNotification().Body;
            Log.Debug(TAG, "Notification Message Body: " + body);
            SendNotification(body, message.Data);
            //new NotificationHelper().CreateNotification(message.GetNotification().Title, message.GetNotification().Body);
        }
        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.notification_template_icon_bg)
                                      .SetContentTitle("FCM Message")
                                      .SetContentText(messageBody)
                                      .SetAutoCancel(true)
                                      .SetContentIntent(pendingIntent);

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

我通过 REST API 发送通知。

var data = new
            {
                to = "/topics/ALL", // Recipient device token
                notification = new {
                    title = "Test",
                    body = "Message",
                    image = "https://cdn.pixabay.com/photo/2015/05/15/14/38/computer-768608_960_720.jpg"
                },
                image = "https://cdn.pixabay.com/photo/2015/05/15/14/38/computer-768608_960_720.jpg"
            };
var jsonBody = JsonConvert.SerializeObject(data);
            bool fcmState;
            using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, "https://fcm.googleapis.com/fcm/send"))
            {
                httpRequest.Headers.TryAddWithoutValidation("Authorization", serverKey);
                httpRequest.Headers.TryAddWithoutValidation("Sender", senderId);
                httpRequest.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

                using (var httpClient = new HttpClient())
                {
                    var result = await httpClient.SendAsync(httpRequest);

                    if (result.IsSuccessStatusCode)
                    {
                        fcmState = true;
                    }
                    else
                    {
                        // Use result.StatusCode to handle failure
                        // Your custom error handler here
                        //_logger.LogError($"Error sending notification. Status Code: {result.StatusCode}");
                    }
                }
            }
  1. 我可以在后台接收通知,但在前台,我只能收到声音,但系统托盘中没有通知。
  2. 当应用在后台运行但未收到图像时,我在系统托盘中收到通知。

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    FCM 通知有两种类型的消息

    • Display-Messages: OnMessageReceived() 仅在您的应用处于前台时回调
    • Data-Messages: OnMessageReceivedd() 回调,即使您的应用程序处于前台/后台/已终止状态。

    对于您的第一个问题,请查看以下有关在 Xamarin 中发送推送通知的文章。

    https://xmonkeys360.com/2019/12/08/xamarin-forms-fcm-setup-configuration-part-i/ https://xmonkeys360.com/2019/12/09/fcm-configuration-in-xamarin-forms-part-ii/

    您应该根据您的第二个要求使用 Data-Message 来接收后台通知。

    {
     "to" : "4OsejRWk8RF72znDZEr",
    
     "data": //Note that here it is sent as Data instead of notification
      {
        "body": "Hello Xamarin",
        "title": "Title"  
        "image": "image url"
      }
    } 
    

    要在收到的通知中接收图像,请使用以下代码。

    var imageReceived = message.Data["image"]; //Make sure you process the received image to required type based on your requirement. 
    var notification = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID);
    notification.SetContentIntent(pendingIntent)
                        .SetContentTitle("FCM Message")
                        .SetContentText(messageBody)
                        .SetLargeIcon(BitmapFactory.DecodeResource(Resources, Resource.Drawable.notification_template_icon_bg))                    .SetSmallIcon(Resource.Drawable.notification_template_icon_bg) //Pass here the image you received if that is your requirement.
                        .SetStyle(new NotificationCompat.BigTextStyle())
                        .SetPriority(NotificationCompat.PriorityHigh)
                        .SetColor(0x9c6114)
                        .SetAutoCancel(true);
    notificationManager.Notify(MainActivity.NOTIFICATION_ID, notification.Build());
    

    【讨论】:

    • 我试过了,但没有在通知中收到图像
    • 请查看我更新的答案。这就是我用来显示图像的方式。
    • @RohanSampat:请注意,您只能将通知作为 JSON 中的数据发送给 Android。对于 iOS,您只需将其作为通知发送。
    • @RohanSampat:如果我的回复对您有帮助,请记得将我的回复标记为答案。谢谢...
    • 通过您的回答,我能够发送包含所有详细信息和图像 URL 的数据对象,但为了显示我必须从 URL 下载它。我已经发布了解决问题的代码,但感谢您建议通过“数据”对象而不是“通知”发送数据。
    【解决方案2】:

    我刚刚通过在从 FCM 接收图像数据时下载图像来解决它。 这是我的代码。

    void SendNotification(string messageBody, IDictionary<string, string> data, RemoteMessage message)
        {
            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 test = message.GetNotification().Body;
            string title = data["title"];
            string body = data["body"];
            string imageReceived = data["image"]; //It contains image URL.
            GetImageBitmapFromUrl(imageReceived); // This method will download image from URL.
            var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
                                      .SetSmallIcon(Resource.Drawable.logo)
                                      .SetContentTitle(title)
                                      .SetContentText(body)
                                      .SetStyle(new NotificationCompat.BigPictureStyle().BigPicture(imageBitmap)) //// This will show the image in system tray.
                                      .SetAutoCancel(true)
                                      .SetContentIntent(pendingIntent);
    
            var notificationManager = NotificationManagerCompat.From(this);
            notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
        }
    

    如果 Data IDictionary 中的 'image' 键中有链接,则下载图像的代码。

    Bitmap imageBitmap = null;
        Bitmap roundedImage = null;
        public Bitmap GetImageBitmapFromUrl(string url)
        {
            using (var webClient = new System.Net.WebClient())
            {
                var imageBytes = webClient.DownloadData(url);
                if (imageBytes != null && imageBytes.Length > 0)
                {
                    imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
                    roundedImage = Bitmap.CreateScaledBitmap(imageBitmap, 300, 300, false);
                    //roundedImage = getRoundedShape(resizedImage);
                }
                webClient.Dispose();
            }
            return roundedImage;
        }
    

    我通过 REST API 发送到 FCM 的数据。感谢@Harikrishnan,首先我使用的是 nofitication 对象,它可以工作,但其中没有图像数据。

    var data = new
                {
                    to = "/topics/ALL", // Recipient device token
                    data = new {
                        title = "Test",
                        body = "Message",
                        image = "https://cdn.pixabay.com/photo/2015/05/15/14/38/computer-768608_960_720.jpg"
                    },
                };
    

    【讨论】:

      猜你喜欢
      • 2021-05-07
      • 2018-12-12
      • 2017-08-28
      • 1970-01-01
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 2017-05-18
      相关资源
      最近更新 更多