13

I am trying to make heads-up notification work. Notification is created, but it's not displayed at the top of the app. Here's the code responsible for building a notification:

Notification notification = new NotificationCompat.Builder(context)
                                .setSmallIcon(android.R.drawable.arrow_up_float)
                                .setContentTitle("Check running time - click!")
                                .setContentText(String.valueOf(elapsedTime))
                                .setContentIntent(pendingIntent)
                                .setDefaults(Notification.DEFAULT_ALL)
                                .setPriority(Notification.PRIORITY_HIGH)
                                .setVibrate(new long[0])
                                .build();

The device that I'm trying to run the app is API 21. I've seen many threads, but no solution given works for me.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Paweł Poręba
  • 1,084
  • 1
  • 14
  • 37

6 Answers6

23

You need to do two things:

  1. Make sure that your notification is properly configured. See: https://developer.android.com/guide/topics/ui/notifiers/notifications#Heads-up

  2. AND make sure the phone is properly configured (I think this is where most get stuck).

Step 1. Configure the notification.

First, register your notification channel like so

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        String name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManager.IMPORTANCE_HIGH; //Important for heads-up notification
        NotificationChannel channel = new NotificationChannel("1", name, importance);
        channel.setDescription(description);
        channel.setShowBadge(true);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }

Then, create a notification, like so:

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "1")
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle(textTitle)
        .setContentText(textContent)
        .setDefaults(DEFAULT_SOUND | DEFAULT_VIBRATE) //Important for heads-up notification
        .setPriority(Notification.PRIORITY_MAX); //Important for heads-up notification

Finally, send the notifciations as you would do normally, e.g.:

Notification buildNotification = mBuilder.build();
NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(001, buildNotification);

Step 2. Configure the phone.

I noticed that I have to enable some additional settings on my phone (a Xiaomi Note 3):

Here are some ways to reach the menu:

  1. Long press a notification, in the notification bar.
  2. Go to: Settings > Installed apps > Select your app > Notifications
  3. Improving on the previous step, you can help users partially by sending them to the installed apps menu, by using this intent:

startActivity(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));

Finally, when you reach this menu enable a setting called something like "Floating notification" (the name of this setting varies between devices).

Tom O
  • 2,495
  • 2
  • 19
  • 23
  • 7
    I had this issue on a Samsung S8 (it worked on a Pixel 2). What fixed it in the end was the order of the code. The channel needs creating first as it is in the code above! Uninstall and re-install (to recreate the channel) and it started working on the S8. – Mark Oct 08 '18 at 08:43
  • 3
    Comment by Mark above was key - i.e. I did not know to uninstall and reinstall the app to make notification channel change take effect - Thanks! – gman413 Nov 30 '18 at 20:19
  • 1
    @Mark nailed it. Make sure to re-create the channel if you had previsouly set it up with any importance other than NotificationManager.IMPORTANCE_HIGH, Android will not recreate the channel with same ID, unless you uninstall the app or create a new channel with a different id. – Juliano Mar 24 '19 at 21:35
  • My code worked when I enabled it in the notification settings in the app. Is there any way I should enable that setting when the user Installs the app? – Rehan Oct 29 '19 at 06:15
  • (Oh,) Hi @Mark !! , I am creating the channel on the onCreate() of its FirebaseMessagingService.class but the Manifest keeps creating its own version of a channel ("Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used."). So: At which point of the lifeCycle am I supposed to create this channel? Both the manifest metadata and NotificationChannel redirects to the same String channelId... – Delark Feb 15 '21 at 21:43
  • 1
    Hi @Delark, I was creating the channel as the notification was received in onMessageReceived which might not be the best idea. I had nothing in the manifest related to the channel – Mark Feb 17 '21 at 10:28
  • Thanks @Mark, I guess I'll do the same, but as you mantioned, it kinda makes no sense to be creating a new one on each message sent, specially when there seems to be an option to instantiate a channel as a meta-data in the manifest. Btw this is the only clue I found: "Note: Realistically you’ll create the notification channels separate from when sending your notifications." https://medium.com/exploring-android/exploring-android-o-notification-channels-94cd274f604c – Delark Feb 17 '21 at 16:36
1


your code is almost fine. I'm using DEFAULT_VIBRATE instead of DEFAULT_ALL:

builder.setPriority(Notification.PRIORITY_HIGH);
if (Build.VERSION.SDK_INT >= 21) {
   mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
}

But, you can also set

builder.fullScreenIntent(sameAsContentPendingtIntent);

but ^ this one is non-deterministic. I mean that system choose to display a HeadsUp or launch Intent. In most cases it shows HeadUp, but I'm not counting on it because of Android versions, Manufacturers, launchers and so so on.
Not at last, you also need to define right Notification Channel. I think you had already done this, because you wouldn't see any notification if you don't :-) Oh lovely Android :-) Anyway, I want to say that also NotificationChannel needs to be in high priority:

channel = new NotificationChannel("uniqueId", "name", NotificationManager.IMPORTANCE_HIGH);
channel.enableVibration(true);

And also, I advise to you, check latest opinions at developer.android.com
Google is going to be more strict from now. Not only for notifications but also for 'targetApi', but that is another story, pardon me :-)
Have a nice code today

zegee29
  • 934
  • 7
  • 8
0

try do this :

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
                                .setSmallIcon(android.R.drawable.arrow_up_float)
                                .setContentTitle("Check running time - click!")
                                .setContentText(String.valueOf(elapsedTime))
                                .setContentIntent(pendingIntent)
                                .setDefaults(Notification.DEFAULT_ALL)
                                .setPriority(Notification.PRIORITY_HIGH)
                                .setVibrate(new long[0]);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0, notificationBuilder.build());
Bruno Ferreira
  • 1,561
  • 1
  • 10
  • 17
0

I've encountered the same issue. The solution is simply properly setting the vibration builder.setVibration(NotificationCompat.DEFAULT_VIBRATE).

According to Google:

The notification has high priority and uses ringtones or vibrations on devices running Android 7.1 (API level 25) and lower.

I hope it helps :)

gmartinsnull
  • 1,075
  • 1
  • 12
  • 11
0

The answers provided above were correct, but are partially correct now.

For future readers, notice that

    .setDefaults(Notification.DEFAULT_ALL)
    .setPriority(Notification.PRIORITY_HIGH)

will NOT resolve the problem.

According to "Android for developers", https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Heads-up

Example conditions that might trigger heads-up notifications include the following:

  • The user's activity is in fullscreen mode (the app uses fullScreenIntent).
  • The notification has high priority and uses ringtones or vibrations on devices running Android 7.1 (API level 25) and lower.
  • The notification channel has high importance on devices running Android 8.0 (API level 26) and higher.

Notice that the second solution (which is mostly mentioned under this question), only works for Android 7.1 or lower.

For Android 8.0 and higher, you should create a notification channel whose importance is NotificationManager.IMPORTANCE_HIGH.

Some sample code:

    NotificationChannel channel =
        new NotificationChannel(
        "MY_OWN_CHANNEL_ID",
        "MY_OWN_CHANNEL_NAME",
        NotificationManager.IMPORTANCE_HIGH);

and after that, make sure that your notification builder uses this channel to display

    NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(context)
            .setSmallIcon(smallIcon)
            .setContentTitle("Title")
            .setContentText("Content")
            .setChannelId("MY_OWN_CHANNEL_ID")
            .setPriority(Notification.PRIORITY_HIGH)
            .setVibrate(new long[0]);

Now you should be able to see heads-up notifications properly.

-1

Just use like

 NotificationManager mNotificationManager = (NotificationManager)
            this.getSystemService(Context.NOTIFICATION_SERVICE);

    Intent myintent = new Intent(this, MainActivity.class);
    myintent.putExtra("message", msg);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            myintent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle("ttile")
                    .setStyle(new NotificationCompat.BigTextStyle()
                            .bigText(msg))
                    .setContentText(msg);

    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(1, mBuilder.build());
Enamul Haque
  • 4,789
  • 1
  • 37
  • 50