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

后端 未结 2 1086
隐瞒了意图╮
隐瞒了意图╮ 2021-02-05 09:01

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

I detected that in some cases the notifications are not shown after the notify()

相关标签:
2条回答
  • 2021-02-05 09:31

    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.

    0 讨论(0)
  • 2021-02-05 09:34

    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.

    0 讨论(0)
提交回复
热议问题