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

2022-09-02 22:01:12

我正在测试可堆叠通知(堆叠通知文章)。

我检测到在某些情况下,在运行android 4.X KitKat的设备中调用后不会显示通知。notify()

为了简单地解决问题,我创建了这个代码,它模拟了一个通知(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());
}

这个想法是首先按下按钮1,然后按下按钮2。它在android 5.0 +中效果很好,当点击第二个按钮时,它会显示第一个通知和摘要,但在Android 4.X中,button1不会显示任何内容。

错误在哪里?

谢谢


答案 1

对此的简短回答是,它似乎显示KitKat设备上的堆叠通知不受支持库的自动支持。

既然你要求启发,以下是我基于对两台运行Android 4.4.2的设备的测试得出的发现。我也在使用AppCompat 23.1.1。

当您深入研究库的源代码时,您会发现当显示通知时,它将使用称为the或直接的东西来显示通知。以下是显示此内容的参考方法:SideChannelNotificationManagerNotificationManagerCompat.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);
    }
}

现在,当您在未设置组的情况下显示通知时,将使用有效的通知管理器显示通知,但是如果设置了组,它将尝试使用侧通道发送通知并取消使用通知管理器显示的任何通知,如上述方法所示。

在设置组时使用侧信道的证明,您可以在其中看到以下代码: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);
    }
}

这一切似乎并不是什么大不了的事情,直到您查看该方法在使用 .pushSideChannelQueue(...)SideChannel

它最终寻找一个可以处理默认情况下没有操作的服务,因此该方法只是返回。这就是导致通知永远不会显示的原因。android.support.BIND_NOTIFICATION_SIDE_CHANNEL

兼容性库中有一个抽象类,如果您想编写自己的文档,则可以根据文档实现该,但似乎最好不要在KitKat和以前的设备中使用分组通知。NotificationCompatSideChannelServiceSideChannelService


答案 2

George的解决方案在技术上是正确的,但不是用户友好的,因为它基于必须从用户从电话安全设置手动启用的。NotificationListener

我找到了这种工作方法,还设置了哪些表示单个通知的方法,并通知具有相同ID的每个人,这些ID指定了通知的类别(例如,消息而不是单个对话)。如果未应用特定的分组样式,则通知将作为普通的非分组样式发布。如果发布了分组的通知,它将替换任何单个通知,因为具有所有相同的IDsetGroupSummary(true)

Android的Telegram将此技术应用于KitKat及更低版本的分组通知。