简体   繁体   English

在Android KitKat中调用setGroup()时未显示通知

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

I'm testing the stackable notifications (Stacking Notifications article) . 我正在测试可堆叠通知(Stacking Notifications文章)

I detected that in some cases the notifications are not shown after the notify() call in devices running android 4.X KitKat. 我发现在某些情况下,在运行android 4.X KitKat的设备中,在notify()调用之后没有显示notify()

To simply the problem I created this code that simulates a notification (button1) and a second notification with a summary (button2) 为了简单地解决问题,我创建了这个模拟通知的代码(button1)和带有摘要的第二个通知(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. 这个想法首先按下按钮1然后按下按钮2。 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. 它在android 5.0+中运行良好,显示第一个通知第一个和第二个按钮被点击时的摘要,但在Android 4.X中,button1没有显示任何内容。

Where is the error? 错误在哪里?

Thanks 谢谢

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. 对此的简短回答是,它似乎显示支持库不会自动支持KitKat设备上的堆叠通知。

Since you asked for an enlightenment here are my findings based on testing with two devices running Android 4.4.2. 既然你在这里要求启示我的发现是基于对运行Android 4.4.2的两个设备的测试。 I am also using AppCompat 23.1.1. 我也在使用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. 当您深入了解库的源代码时,您会发现当显示通知时,它将直接使用名为SideChannelNotificationManager来显示通知。 Below is the NotificationManagerCompat.notify method for reference showing this: 下面是NotificationManagerCompat.notify方法,供参考,显示如下:

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: NotificationCompatKitKat.Builder中可以找到在设置组时使用辅助通道的证据,您将在其中看到以下代码:

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 . 在您查看使用SideChannel显示通知时pushSideChannelQueue(...)方法的作用之前,这一切似乎都不是什么大问题。

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. 它最终寻找一个可以处理动作android.support.BIND_NOTIFICATION_SIDE_CHANNEL的服务,默认情况下没有一个,所以该方法只返回。 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. 兼容性库中有一个NotificationCompatSideChannelService抽象类,如果您想编写自己的SideChannelService ,可以根据文档实现,但似乎最好不要在KitKat和之前的设备中使用分组通知。

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. George的解决方案在技术上是正确的,但不是用户友好的,因为它基于NotificationListener ,必须由用户手机安全设置手动启用

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 (eg messages instead single conversation). 我找到了这个工作方法,也将setGroupSummary(true)设置为代表单个通知的那些,并通知具有指定通知类别的相同id的每个人(例如消息而不是单个会话)。 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 . 如果已发布分组的一个,则它将替换任何单个通知,因为它具有相同的ID

Telegram for Android apply this technique to group notifications also on KitKat and lower. Telegram for Android将此技术应用于KitKat及更低版本的组通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM