使用setGroup()在Kitkat(API 19)中堆叠通知无效

8
我有一个问题,找不到答案。我尝试了AndroidDeveloper教程,在stackoverflow和谷歌上搜索,但是要么我的搜索技巧很糟糕,要么没有答案解决我的问题。
当有多个新消息时,我想将消息通知堆叠在一个通知中。我可以为每个消息显示一个通知,但我无法创建一条堆叠/汇总通知。
最好的结果是这样的:http://developer.android.com/images/android-5.0/notifications/Summarise_Dont.png 我想要的是这样的:http://developer.android.com/images/android-5.0/notifications/Summarise_Do.png 我正在使用API 19,不需要向后兼容。在AndroidStudio中编写代码并在Genymotion中进行测试。
我尝试使用NotificationCompatManager,结果是多个通知: NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); 我还尝试使用NotificationManager,结果也是多个通知: NotificationManager notificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 我的通知如下: Notification notification = new NotificationCompat.Builder(this) .setContentTitle( "New message from... ") .setContentText("Message:...") .setSmallIcon(R.drawable.icon) .setContentIntent(pIntent) .setSound(RingtoneManager.getDefaultUri(TYPE_NOTIFICATION)) .setGroup(mNoti) .setGroupSummary(true) .setAutoCancel(true) .build(); 我这样触发通知:
notificationManager.notify(counter, notification);

计数器会为每个通知递增,因此每个通知都有自己的ID。

我也尝试过使用这种形式构建和触发通知,但没有成功:

  NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.icon)
                    .setContentTitle("message from...")
                    .setContentText("message...")
                    .setContentIntent(pIntent)
                    .setAutoCancel(true)
                    .setGroup(mNoti)
                    .setGroupSummary(true)
                    .setSound(RingtoneManager.getDefaultUri(TYPE_NOTIFICATION));


    notificationManager.notify(counter, notificationBuilder.build());

setGroup 显然对我没有作用。我不明白为什么它不起作用或者我应该如何使其工作。

我的组看起来像这样:

final static String mNoti = "mNoti";

唯一与我想要的接近的方法是为所有通知使用相同的ID,以便新通知覆盖旧通知,并在构建通知时使用setNumber(int)。但是这并不能真正给我想要的结果,因为我不认为我可以获得用户未处理的通知数量。或者我可以吗?

有人能帮我达到我的目标吗?

1个回答

1
你之所以得到类似于http://developer.android.com/images/android-5.0/notifications/Summarise_Dont.png的结果,是因为你在所有通知上都将组摘要设置为true。在API文档中,它被描述为:将此通知设置为一组通知的组摘要。这意味着每个通知都将被视为摘要,并因此显示为新通知。
为了解决你的问题,你可以在每次收到新通知时发送一个新的摘要。请注意,我并不100%确定这是最好的解决方案,但它可以解决问题。 我创建了一个测试应用程序,根据按钮点击添加通知:
public class MyActivity extends Activity {

    private final static String GROUP_KEY_MESSAGES = "group_key_messages";
    public static int notificationId = 0;
    private NotificationManagerCompat manager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        manager = NotificationManagerCompat.from(this);
        manager.cancelAll();
    }

    public void addNotification(View v) {
        notificationId++; // Increment ID

        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

        Intent viewIntent = new Intent(this, ShowNotificationActivity.class);
        viewIntent.putExtra("notificationId", notificationId); // Put the notificationId as a variable for debugging purposes

        PendingIntent viewPendingIntent = PendingIntent.getActivity(this, notificationId, viewIntent, 0); // Intent to next activity

        // Group notification that will be visible on the phone
        Notification summary = new NotificationCompat.Builder(this)
                .setAutoCancel(true)
                .setContentIntent(viewPendingIntent)
                .setContentTitle("New notifications")
                .setContentText("You have "+notificationId+" new messages")
                .setLargeIcon(icon)
                .setGroup(GROUP_KEY_MESSAGES)
                .setGroupSummary(true)
                .build();

        manager.cancelAll(); // Is this really needed?
        manager.notify(notificationId, summary); // Show this summary
    }
}

ShowNotificationActivity:
public class ShowNotificationActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_notification);

        Intent intent = getIntent();
        int counter = intent.getIntExtra("COUNTER", -57);
        Log.d("COUNTER", ""+counter);

        TextView view = (TextView)(findViewById(R.id.textView));
        view.setText("You have just read "+counter+" messages");
        MyActivity.notificationId = 0; // Reset ID. Should not be done like this, but used to show functionality.
    }
}

第一个活动MyActivity用于处理通知。不过我猜这通常是在接收器中完成的。在MyActivity中,一个按钮会触发addNotification,推送新的通知摘要。在添加摘要之前,所有旧的摘要都会被取消。点击摘要时,你将进入启动活动,称为ShowNotificationActivty,其中会显示数据。如果这是一个电子邮件应用程序,MyActivity将是某种保存电子邮件到数据库的电子邮件接收器。notificationId可以设置为保存在数据库中的某个id。当点击通知时,可以基于notificationId查看电子邮件。希望这有所帮助:)

1
我按照你的建议使用了setGroupSummary和setGroup,虽然只在Android 5.0及以上版本上有效。4.4和4.2会分别显示每个通知。这超出了原来的问题范围,所以我创建了一个新的问题:https://dev59.com/vVwZ5IYBdhLWcg3waft6 - Anton Cherkashyn
@AntonCherkashyn 你确定已经包含了这行代码:manager.cancelAll(); // Is this really needed? 吗?这是关闭旧通知只留下摘要的“诀窍”。 - Pphoenix
我尝试过这个方法,然后在手机上只看到了摘要通知,没错,但我的最终目标是在Android Wear上有堆叠通知,为此我必须触发N个单独的通知+每个android开发人员指南中的1个摘要通知:https://developer.android.com/training/wearables/notifications/stacks.html。调用manager.cancelAll();也会在Android Wear上关闭通知。因此,这不起作用,因为这些单独的通知具有自定义操作/页面等。 - Anton Cherkashyn
@AntonCherkashyn 啊,没错!我从未在Android Wear上测试过这个,取消然后添加摘要感觉像是一个丑陋的hack,只是碰巧在手机上起作用。 :) - Pphoenix
1
我找出了错误并更新了问题。我使用的是NotificationManager而不是NotificationManagerCompat。一旦我切换到compat,通知就开始正常工作了。 - Anton Cherkashyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接