locked
How to get notification "quick display" at the top of device RRS feed

  • Question

  • User392382 posted

    Does anybody know what this is called when a notification does this "quick display" thing at the top of the device for 1-2 seconds before going away and just having the icon in the notification tray? Is this a setting that has to be specified when building out the notification using NotificationCompat.Builder? Is it a setting elsewhere?

    Here is where I took the screenshot. You can see the full GIF in action from the point of the user clicking the button to send the notification, the notification being received, the "quick display" thing that I'm asking about, and then the notification disappearing into the tray.

    I've been trying to get my own Xamarin.Forms application to do it but instead when I get a notification it immediately goes to showing the tray icon and that's it.

    Wednesday, April 22, 2020 8:13 PM

Answers

  • User369979 posted

    Not only a single value we still need to initialize a channel:

    var importance = NotificationImportance.High;
    NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, "Urgent", importance);
    chan.EnableVibration(true);
    chan.LockscreenVisibility = NotificationVisibility.Public;
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 24, 2020 2:54 AM
  • User392382 posted

    @LandLu said: Not only a single value we still need to initialize a channel:

    var importance = NotificationImportance.High;
    NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, "Urgent", importance);
    chan.EnableVibration(true);
    chan.LockscreenVisibility = NotificationVisibility.Public;
    

    For me, setting the channel importance (or priority) to High is what fixed it.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, April 29, 2020 5:21 PM

All replies

  • User185808 posted

    This can be achieved by using Acr.UserDialogs

    IUserDialogs dialog = UserDialogs.Instance;
    dialog.Toast(new ToastConfig("Text to whow")
      .SetDuration(TimeSpan.FromSeconds(3))
      .SetPosition(ToastPosition.Top)
      .SetAction(x => x.SetText("Ok")
    ));
    
    Thursday, April 23, 2020 5:26 AM
  • User369979 posted

    It depends on what kind of notification you are sending from the FCM: https://stackoverflow.com/questions/55737110/notification-for-android-what-is-different-between-notification-and-data-payloa The notification type will be handled by the system and only leaves at the notification tray. It won't pop a top alert as you displayed in the link. However, data type will be delivered from your application itself. Here is a format of my notification sending from Azure Notification Hub:

    {"data":{"message":"Notification Hub test notification"}}
    

    And the alert will be displayed:

    Thursday, April 23, 2020 9:30 AM
  • User392382 posted

    @LandLu
    Thanks LandLu.

    Here's what my request payload looks like. I believe this should be treated like a data request but I still don't get the top alert.

    {"data": { "title":"title", "body":"body", "randomData":"data1", "randomData2":"data2" } }

    Is there another setting that needs to get set somewhere while I'm handling the notification when I receive it?

    Thursday, April 23, 2020 12:03 PM
  • User369979 posted

    When the notification comes OnMessageReceived will be called:

    public override void OnMessageReceived(RemoteMessage message)
    {
        // ...
    }
    

    We could create a notification in this event:

    var importance = NotificationImportance.High;
    NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, "Urgent", importance);
    chan.EnableVibration(true);
    chan.LockscreenVisibility = NotificationVisibility.Public;                    
    
    var intent = new Intent(this, typeof(MainActivity));
    intent.AddFlags(ActivityFlags.ClearTop);
    var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
    
    var notificationBuilder = new NotificationCompat.Builder(this)
        .SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
        .SetContentTitle("Title")
        .SetContentText("Body")
        .SetContentIntent(pendingIntent)
        .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
        .SetAutoCancel(true)
        .SetChannelId(URGENT_CHANNEL);
    
    NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
    notificationManager.CreateNotificationChannel(chan);
    
    notificationManager.Notify(NOTIFY_ID, notificationBuilder.Build());
    
    Friday, April 24, 2020 2:29 AM
  • User392382 posted

    Here is my current SendLocalNotification method (which my OnMessageReceived calls). I currently have a notification that comes through with 2 actions.

    ``` void SendLocalNotification(string body) { //Unique request code to avoid PendingIntent collision. var requestCode = new Random().Next();

            // accept intent
            var acceptIntent = new Intent(this, typeof(MainActivity));
            acceptIntent.SetAction("ACCEPT_ACTION");
            var pendingIntentAccept = PendingIntent.GetActivity(this, requestCode, acceptIntent, PendingIntentFlags.OneShot);
    
            // decline intent
            var declineIntent = new Intent(this, typeof(MainActivity));
            declineIntent.SetAction("DECLINE_ACTION");
            var pendingIntentDecline = PendingIntent.GetActivity(this, requestCode, declineIntent, PendingIntentFlags.OneShot);
    
            var notificationBuilder = new NotificationCompat.Builder(this)
                .AddAction(0, "Accept", pendingIntentAccept)
                .AddAction(0, "Decline", pendingIntentDecline)
                .SetContentTitle("Content Title")
                .SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
                .SetContentText("content text")
                .SetContentInfo("content info") // i think content info and sub-text overwrite each other
                .SetSubText("sub text")
                .SetAutoCancel(true)
                .SetShowWhen(true)
                .SetContentIntent(pendingIntentAccept)
                .SetContentIntent(pendingIntentDecline);
    
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
            }
    
            var notificationManager = NotificationManager.FromContext(this);
            notificationManager.Notify(0, notificationBuilder.Build());
        }
    

    ```

    Friday, April 24, 2020 2:40 AM
  • User369979 posted

    Did you create a channel like what I posted above? Starting in Android 8.0 (API level 26), all notifications must be assigned to a channel. I saw you have set a channel id from your code:

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

    Did you create it before this?

    Friday, April 24, 2020 2:48 AM
  • User392382 posted

    It's pulling this value:

    public static string NotificationChannelName { get; set; } = "XamarinNotifyChannel";

    Friday, April 24, 2020 2:50 AM
  • User369979 posted

    Not only a single value we still need to initialize a channel:

    var importance = NotificationImportance.High;
    NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, "Urgent", importance);
    chan.EnableVibration(true);
    chan.LockscreenVisibility = NotificationVisibility.Public;
    
    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, April 24, 2020 2:54 AM
  • User392382 posted

    OK so I modified the method to below. I still received the notification but no top alert. Just goes straight to the tray.

    ``` void SendLocalNotification(string body) { var chan = new NotificationChannel(AppConstants.NotificationChannelName, "Urgent", NotificationImportance.High); chan.EnableVibration(true); chan.LockscreenVisibility = NotificationVisibility.Public;

            //Unique request code to avoid PendingIntent collision.
            var requestCode = new Random().Next();
    
            // accept intent
            var acceptIntent = new Intent(this, typeof(MainActivity));
            acceptIntent.SetAction("ACCEPT_ACTION");
            var pendingIntentAccept = PendingIntent.GetActivity(this, requestCode, acceptIntent, PendingIntentFlags.OneShot);
    
            // decline intent
            var declineIntent = new Intent(this, typeof(MainActivity));
            declineIntent.SetAction("DECLINE_ACTION");
            var pendingIntentDecline = PendingIntent.GetActivity(this, requestCode, declineIntent, PendingIntentFlags.OneShot);
    
            var notificationBuilder = new NotificationCompat.Builder(this)
                .AddAction(0, "Accept", pendingIntentAccept)
                .AddAction(0, "Decline", pendingIntentDecline)
    
                .SetContentTitle("Content Title")
                .SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
                .SetContentText("content text")
                .SetContentInfo("content info") // i think content info and sub-text overwrite each other
                .SetSubText("sub text")
                .SetTimeoutAfter(60000)
                .SetAutoCancel(true)
                .SetShowWhen(true)
                .SetContentIntent(pendingIntentAccept)
                .SetContentIntent(pendingIntentDecline);
    
            var notificationManager = NotificationManager.FromContext(this);
            notificationManager.CreateNotificationChannel(chan);
            notificationManager.Notify(0, notificationBuilder.Build());
        }
    

    ```

    Friday, April 24, 2020 3:00 AM
  • User369979 posted

    Use this to create a channel:

    NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
    

    Please precisely follow my code to create a notification.

    Friday, April 24, 2020 3:02 AM
  • User392382 posted

    No difference. Still just goes straight to the tray.

    Friday, April 24, 2020 3:08 AM
  • User369979 posted

    Try to add a breakpoint at the method to see whether your application will go into this function. Will it work when your application is on the foreground?

    Friday, April 24, 2020 3:13 AM
  • User392382 posted

    Yes it goes through the entire method without error and will send a notification if the app is in both the foreground and background.

    Friday, April 24, 2020 3:16 AM
  • User369979 posted

    Do you mean it works when your application is in the background and foreground? Have you added these permissions: https://github.com/firebase/quickstart-android/issues/368

    Friday, April 24, 2020 3:33 AM
  • User392382 posted

    Yes I receive the notification and it calls OnMessageReceived in both the foreground and background.

    Friday, April 24, 2020 3:43 AM
  • User369979 posted

    Is the effect what you want when in the foreground and background?

    Friday, April 24, 2020 3:58 AM
  • User392382 posted

    Preferably both

    Friday, April 24, 2020 11:59 AM
  • User369979 posted

    The notification popup will be displayed in both the foreground and the background. If this is what you want. Was this issue solved on your side?

    Sunday, April 26, 2020 1:38 AM
  • User392382 posted

    @LandLu I was able to figure out what was going on with my notification. For future reference for anybody who might be wondering, it's called a Heads Up Display to get your notification to display for 2-3 seconds before going to the notification tray. Once I figured out this is what it was called I found a thread (here) that basically said the same thing you were saying about setting up the channel.

    I misunderstood what you were asking about setting up the channel previously before building out my notification and it turns out I was. I was building it in MainActivity and then referencing the channel name in all my firebase stuff:

    ``` void CreateNotificationChannel() { // Notification channels are new as of "Oreo". // There is no need to create a notification channel on older versions of Android. if (Build.VERSION.SdkInt >= BuildVersionCodes.O) { var channelName = AppConstants.NotificationChannelName; var channelDescription = string.Empty; var channel = new NotificationChannel(channelName, channelName, NotificationImportance.Default) { Description = channelDescription };

                var notificationManager = (NotificationManager)GetSystemService(NotificationService);
                notificationManager.CreateNotificationChannel(channel);
            }
        }
    

    ```

    Once I changed this line: var channel = new NotificationChannel(channelName, channelName, NotificationImportance.Default) to this: var channel = new NotificationChannel(channelName, channelName, NotificationImportance.High) it started displaying the heads up display.

    Wednesday, April 29, 2020 5:19 PM
  • User392382 posted

    @LandLu said: Not only a single value we still need to initialize a channel:

    var importance = NotificationImportance.High;
    NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, "Urgent", importance);
    chan.EnableVibration(true);
    chan.LockscreenVisibility = NotificationVisibility.Public;
    

    For me, setting the channel importance (or priority) to High is what fixed it.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, April 29, 2020 5:21 PM