【问题标题】:Xamarin Forms - Android - FCM - Heads up notification when app is in foreground, background and swiped closedXamarin Forms - Android - FCM - 当应用程序处于前台、后台和滑动关闭时提醒通知
【发布时间】:2020-07-08 21:02:42
【问题描述】:

我需要一些有关 android 推送通知的帮助。对于上下文,我已经阅读了数十篇关于如何为 android 实现推送通知的堆栈溢出帖子。我看到的所有帖子都只涵盖了部分问题。当应用程序处于前台或后台时,我已经能够成功接收推送通知并显示提示通知,但是当应用程序被刷关闭时它不起作用。为了在应用滑动关闭时在状态栏上显示通知,您需要在有效负载中使用“通知”对象而不是“数据”对象。

我想要实现的是 - 当应用程序处于任何这些状态时 - 前景、背景和滑动关闭时,我需要状态栏通知、声音和抬头通知。

实现这一点的代码、payload json 和清单配置的秘诀是什么?我手机上的任何主要应用程序 - eBay、etsy、亚马逊和我下载的大多数应用程序都可以完成所有这些,因此无论 fcm 指南中的某些内容怎么说,它都必须是可能的。

这是 FireBaseMessagingService 中的 onMessageReceived 方法:

  public override void OnMessageReceived(RemoteMessage message)
  {
    try
    {
        base.OnMessageReceived(message);
        string messageBody = string.Empty;
        string messageTitle = string.Empty;

        if (message.GetNotification() != null)
        {
            messageTitle = message.GetNotification().Title;
            messageBody = message.GetNotification().Body;
        }
        else
        {
            if (message.Data.Values.Count == 1)
            {
                messageTitle = "Alerts Occurred";
                messageBody = message.Data.Values.First();
            }
            else if (message.Data.Values.Count == 2)
            {
                messageTitle = message.Data.Values.ToList()[0];
                messageBody = message.Data.Values.ToList()[1];
            }
        }

        SendLocalNotification(messageTitle, messageBody);

    }
    catch (Exception e)
    {
        NotificationHubHelper.LogInfo($"Error receiving message on device: {e.Message}");
    }
  }

   private void SendLocalNotification(string title, string body)
  {
    try
    {
        _notificationBadgeCount++;
        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.ClearTop);
        intent.PutExtra("message", body);
        var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

        int notificationIconId = 
Resources.GetIdentifier(NotificationHubHelper.AndroidNotificationIconImage, "drawable", 
AppInfo.PackageName);
        NotificationHubHelper.LogInfo($"Found notification icon with id: {notificationIconId}");
        var notificationBuilder = new NotificationCompat.Builder(this, 
NotificationHubHelper.NotificationChannelName)
            .SetContentTitle(title)
            .SetSmallIcon(notificationIconId) //.SetSmallIcon(ApplicationInfo.Icon)
            .SetContentText(body)
            .SetAutoCancel(true)
            .SetShowWhen(false)
            .SetContentIntent(pendingIntent)
            .SetPriority((int)NotificationPriority.Max);

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            notificationBuilder.SetChannelId(NotificationHubHelper.NotificationChannelName);
        }

        var notificationManager = NotificationManager.FromContext(this);
        notificationManager.Notify(0, notificationBuilder.Build());
        CrossBadge.Current.SetBadge(_notificationBadgeCount);
    }
    catch (Exception e)
    {
        NotificationHubHelper.LogInfo($"Error sending local notification on device: {e.Message}");
    }
 }

这是我们的清单:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" 
    android:versionName="1.0.9" package="HIDDEN_FROM_POST" android:installLocation="auto">
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="29" />
    <application android:allowBackup="false" android:label="HIDDEN_FROM_POST" 
    android:icon="@drawable/HIDDEN_FROM_POST">
        <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="HIDDEN_FROM_POST" />
        <meta-data android:name="com.google.android.gms.version" 
    android:value="@integer/google_play_services_version" />
        <uses-library android:name="org.apache.http.legacy" android:required="false" />
        <provider android:name="android.support.v4.content.FileProvider" 
    android:authorities="${applicationId}.fileprovider" android:exported="false" 
    android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
    android:resource="@xml/file_paths"></meta-data>
        </provider>
        <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>
    <meta-data
      android:name="com.google.firebase.messaging.default_notification_icon"
      android:resource="@drawable/HIDDEN_FROM_POST" />
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
  <uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
  <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
  <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS"/>
  <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
  <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
  <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
  <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" /> 
  <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
  <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
  <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
  <uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE" />
</manifest>

最后,这是我们尝试过的最新有效载荷:

   {
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    },
    "data":{
        "message":"this is a message",
        "title":"title"
    }
}

通过以上方式,我们在应用被滑动关闭时收到状态栏通知,在应用处于后台时收到状态栏通知,在应用处于前台时收到带有抬头通知的状态栏通知。

我们如何在所有场景中获得提醒通知?

镜头

【问题讨论】:

    标签: android xamarin.forms push-notification firebase-cloud-messaging


    【解决方案1】:

    与普通通知基本相同。在Android 8.0及之后的版本中,您只能通过在通知通道的重要性上将重要性级别设置为IMPORTANCE_HIGH来暂停通知。例如:

    NotificationChannel notificationChannel = new NotificationChannel("","",NotificationImportance.High);
    

    它还允许用户直接在手机上设置通知的重要性级别。可实现紧急暂停。

    对于 8.0 之前的 Android 版本,将 SetFullScreenIntent 添加到 notificationBuilder

    notificationBuilder.SetFullScreenIntent(pendingIntent,true); 
    

    或激活声音和振动提示。

    【讨论】:

    • 谢谢。我们确实将通知通道设置为高(在我们的例子中是最大)优先级。但是,当应用程序在后台或滑动关闭时,我们不会收到提醒通知。只有当应用程序处于前台时,我们才会得到提示。真的,这是我们想要实现的最重要的事情。我们已经完成了我们想要的其他工作。
    • @LenVanerstrom 您是否尝试使用铃声或振动?
    【解决方案2】:

    这可能是一个长镜头,但经过大量挖掘后,我发现当在后台,特别是在被刷掉时,您无法访问 XamarinForms 对象,因为它只有在您实际完成启动活动时才会被实例化。

    例如如果这实际上是在使用 DependencyService 或其他 Forms 库,则会出现错误。

    CrossBadge.Current.SetBadge(_notificationBadgeCount)
    

    还要确保在您的通知服务器中您将优先级设置为high,默认情况下这是正常的,如果刷掉不会导致应用程序唤醒。

    priority: "high",
    
    android: {
        priority: "high",
        notification: {
            title: title,
            body: body,
            sound: "default",
            priority: "high",
            sticky: false,
            defaultSound: true,
            defaultVibrateTimings: true,
        },
        data: {        
           title: title,
           body: body
       }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 2019-11-02
      • 2017-06-25
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      相关资源
      最近更新 更多