Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack notifications in Kitkat (API 19) using setGroup() not working

I have a problem that I can't find the answer to. I have tried the AndroidDeveloper tutorials, I have searched here on stackoverflow and on google but either my search-skills are awefull or there's no answer I think answers my problem.

I want to stack message notifications into one notification for all new messages when there are more than one. I can make a notification appear for each message but I cannot make a stack/summary notification.

The best I get is this : http://developer.android.com/images/android-5.0/notifications/Summarise_Dont.png

What I want is this : http://developer.android.com/images/android-5.0/notifications/Summarise_Do.png

I am using API 19 and it does not have to be back-compatible. Writign my code in AndroidStudio and testing in Genymotion.

I have tried using NotificationCompatManager with the result of having multiple notifications: NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

I have also tried using NotificationManager with the same result, that is multiple notifications:

NotificationManager notificationManager=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

My notification looks like this:

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();

And I fire the notification like this:

notificationManager.notify(counter, notification);

Where counter increments for each notification so each notification has its own ID.

I have also tried this form for building and fiering the notification without succsess:

  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 obviously does noting for me. I don't understand why it doesn't work or how I'm supposed to make it work.

my group look like this:

final static String mNoti = "mNoti";

The only thing that comes remotely close to what I want is using the same ID for all notifications so that the new notifications overrides the old ones, and using setNumber(int) while building the notification. However this doesn't truely give me the result I want because I don't think I can get the number of notifications not handled by the user. Or can I?

Can anyone help me arrive at my desired goal?

like image 236
Nika Avatar asked Oct 21 '14 13:10

Nika


1 Answers

The reason you are getting results as in http://developer.android.com/images/android-5.0/notifications/Summarise_Dont.png is because you set group summary to true on all your notifications. In the API docs it is described as: Set this notification to be the group summary for a group of notifications. This means that every notification will be treated as a summary, and thus will be displayed as a new notification.

To solve your problem, you can send a new summary every time you get a new notification. Note that I am not 100% sure that this is the best solution, but it solves the problem. I created a test application which adds notifications based on button clicks:

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.
    }
}

The first activity MyActivity is used to handle notifications. I guess that this is mostly done in receivers though. A button in MyActivity triggers addNotification which pushes the new notification summary. Before adding the summary all old summaries are cancelled. when clicking on the summary you get to the startup activity, called ShowNotificationActivty where data is shown. If this was, for instance, an email app, MyActivity would be some sort of email receiver which saved the email to a database. The notificationId could be set to some id saved in the database. When the notifications are clicked, the email can be viewed based on notificationId.

I hope this helps :)

like image 65
Pphoenix Avatar answered Nov 08 '22 18:11

Pphoenix