Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Notification not shown when setGroup() is called in Android KitKat

I'm testing the stackable notifications (Stacking Notifications article).

I detected that in some cases the notifications are not shown after the notify() call in devices running android 4.X KitKat.

To simply the problem I created this code that simulates a notification (button1) and a second notification with a summary (button2)

private final static int NOTIFICATION_ID_A=6;
private final static int NOTIFICATION_ID_B = 7;
private final static int NOTIFICATION_ID_SUMMARY = 8;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showNotif(NOTIFICATION_ID_A,false);
        }
    });
    findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showNotif(NOTIFICATION_ID_B,false);
            showNotif(NOTIFICATION_ID_SUMMARY,true);
        }
    });
}

private void showNotif(int notificationId,boolean groupSummary) {
    CharSequence title="Title "+notificationId;
    CharSequence message="Message "+notificationId;
    NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this);
    notifBuilder.setSmallIcon(R.drawable.icon_notifications);
    notifBuilder.setContentTitle(title);
    notifBuilder.setContentText(message);
    notifBuilder.setGroupSummary(groupSummary);
    notifBuilder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT));
    notifBuilder.setGroup("group_" + 1);
    NotificationManagerCompat.from(this).notify(notificationId, notifBuilder.build());
}

The idea is first to press the button1 and then the button2. It works great in android 5.0+ showing the first notif first and the summary when the second button is clicked, but in Android 4.X the button1 does not show anything.

Where is the error?

Thanks

like image 343
Addev Avatar asked Jul 14 '15 13:07

Addev


People also ask

Why do my notifications disappear Android?

Do Not Disturb or Airplane Mode is on. Either system or app notifications are disabled. Power or data settings are preventing apps from retrieving notification alerts. Outdated apps or OS software can cause apps to freeze or crash and not deliver notifications.

How do I stack notifications on Android?

To create a stack, call setGroup() for each notification you want in the stack and specify a group key.

How do I group push notifications on Android?

To add a group summary, proceed as follows: Create a new notification with a description of the group—often best done with the inbox-style notification. Add the summary notification to the group by calling setGroup() . Specify that it should be used as the group summary by calling setGroupSummary(true) .


2 Answers

The short answer to this is that it appears showing a stacked notification on a KitKat device is not automatically supported by the support library.

Since you asked for an enlightenment here are my findings based on testing with two devices running Android 4.4.2. I am also using AppCompat 23.1.1.

When you dig into the source code of the library you will find that when a notification is shown it will either use something called the SideChannel or the NotificationManager directly to show the notification. Below is the NotificationManagerCompat.notify method for reference showing this:

public void notify(String tag, int id, Notification notification) {
    // MY COMMENT: true when the notification has the extra 
    // NotificationCompatJellybean.EXTRA_USE_SIDE_CHANNEL set to true.
    if (useSideChannelForNotification(notification)) {
        pushSideChannelQueue(new NotifyTask(mContext.getPackageName(), id, tag, notification));
        // Cancel this notification in notification manager if it just transitioned to being
        // side channelled.
        IMPL.cancelNotification(mNotificationManager, tag, id);
    } else {
        // MY COMMENT: this calls notificationManager.notify(id, notification); in the base implementation
        IMPL.postNotification(mNotificationManager, tag, id, notification);
    }
}

Now when you show a notification without setting a group the notification is shown using the notification manager which works, but if a group is set it will attempt to use the side channel to send the notification and cancel any notification shown using the notification manager as seen in the above method.

Proof that the side channel is used when a group is set is found in NotificationCompatKitKat.Builder where you will see the following code:

if (groupKey != null) {
    mExtras.putString(NotificationCompatJellybean.EXTRA_GROUP_KEY, groupKey);
    if (groupSummary) {
        mExtras.putBoolean(NotificationCompatJellybean.EXTRA_GROUP_SUMMARY, true);
    } else {
        mExtras.putBoolean(NotificationCompatJellybean.EXTRA_USE_SIDE_CHANNEL, true);
    }
}

This all does not seem like a big deal until you look at what the pushSideChannelQueue(...) method does when showing a notification using the SideChannel.

It ends up looking for a service that can handle the action android.support.BIND_NOTIFICATION_SIDE_CHANNEL of which there is not one by default so the method simply returns. This is what is causing the notification to never be shown.

There is a NotificationCompatSideChannelService abstract class in the compatibility library that you can implement according to the documentation if you want to write your own SideChannelService but it seems like you are better off just not using grouped notifications in KitKat and prior devices.

like image 125
George Mulligan Avatar answered Oct 19 '22 19:10

George Mulligan


The solution of George is technically right but is not user-friendly because is based on a NotificationListener that has to be enabled manually from phone security setting by user.

I find this working method, set setGroupSummary(true) also to which ones that represent single notification and notify everyone with same id that specify the category of the notification (e.g. messages instead single conversation). If no particular grouping style is applied, the notification is posted as a normal non-grouped one. If a grouped one is posted, it will replace any single notification because have all the same id.

Telegram for Android apply this technique to group notifications also on KitKat and lower.

like image 22
Alessandro Borile Avatar answered Oct 19 '22 18:10

Alessandro Borile