Canceling Notififcations Android Java

86 views Asked by At

I started working with Notifications and to improve user expirirence I added button to notification "MARK AS READ", so when it is pressed - message will hide;

I had a few problems, in database each message has "read" field which is boolean, in method onDataChange() I loop and check if any of messages have this field as false if they have I call makeNotification(), looks fine, where is problem??? - e.x. I have 2 notifications, I cancel one(the app goes to database and change field to true, so now onDataChange() will be called), but another isn't cancelled and because onDataChange() was called now I have same notification appeared twice.....

I tried to fix this by building array of messages that are read and already displayed, not the best solution I think, but even previous problem was somehow solved this is a wierd one. When notitifcation appears in notification list it has button "MARK AS READ", when I press it notififcation hides, but only if I start from the highest to the lower ones, so if I press second notification first foldes, if I press third first folds..

In onCreate() counter is set to 1;

public void makeNotification()
{
    Intent activityIntent  = new Intent(this, Notifications.class);
    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, activityIntent, 0);

    Intent broadcastIntent = new Intent(getApplicationContext(), NotifUpdater.class);
    broadcastIntent.putExtra("seconds", message.getSeconds());
    broadcastIntent.putExtra("id", String.valueOf(counter));

    PendingIntent actionIntent = PendingIntent.getBroadcast(this, 0,
            broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_ID)
            .setVibrate(new long[]{100, 0, 100})
            .setSmallIcon(R.drawable.ic_shield)
            .setContentTitle(message.getTime() + " | " + message.getClient())
            .setContentText(message.getMessage())
            .setContentIntent(contentIntent)
            .setAutoCancel(true)
            .setOnlyAlertOnce(true)
            .addAction(0, "MARK AS READ", actionIntent)
            .build();

    notificationManager.notify(counter, notification);
    counter += 1;
}

// Broadcast which is triggered by pressing button
public class NotifUpdater extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    String seconds = intent.getStringExtra("seconds");
    int id = Integer.parseInt(intent.getStringExtra("id"));
    database.getReference("latest").child(seconds).child("read").setValue(true);

    NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
    notificationManager.cancel(id);
    }
}
2

There are 2 answers

0
NizarETH On BEST ANSWER

You should have : FLAG_CANCEL_CURRENT like :

PendingIntent actionIntent = PendingIntent.getBroadcast(this, NOTIFICATION_ID, buttonIntent, PendingIntent.FLAG_CANCEL_CURRENT);

not FLAG_UPDATE_CURRENT

0
Dan Baruch On

Regarding your first issue, I'd just set an indicator for each notification, "wasShown" or something of the sort that is only set to true once you have showed the notification and when ever you are iterating your notifications, only show those who has "wasShown" set to false.

Regarding your 2nd problem, I'm not familiar with FirebaseDatabase but it sounds like its an ID problem. Did you make sure the ID you are getting from the intent is the right one?