4

I want to change the notification smallIcon in the status bar while a foreground service is running, depending on the status the service gathers, namely "mute" or "unmute".

What is needed to display alternate smallIcons from the res.drawable resouce?

In the initialize method of the service class, I currently set the mute icon as follows, but I don't know how to change it after the service was started:

NotificationCompat.Builder builder = new NotificationCompat.Builder(
        this, NOTE_CHANNEL_ID)
        .setSmallIcon(R.drawable.mute_icon)
        .setContentTitle("Calm: Running")
        .setContentText(this.getString(R.string.calm_close_txt))
        .setOngoing(true)
        .setContentIntent(stopIntent);

startForeground(NOTIFICATION_ID, builder.build());
sbolel
  • 3,486
  • 28
  • 45
monok
  • 494
  • 5
  • 16

2 Answers2

2

The workaround is to just create a new notification with a new icon, so it'll replace the old one.

EDIT: Here's a sample code for creating a new notification every time a button is clicked with a sample logic based on a boolean variable called indicator.

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //Create the notification builder object
        NotificationCompat.Builder builder = new NotificationCompat.Builder(v.getContext(), NOTE_CHANNEL_ID)
                .setSmallIcon(indicator ? R.drawable.icon1 : R.drawable.icon2)   //TODO: change this line with your logic
                .setContentTitle("Your notification title here")
                .setContentText("Your notificiation text here")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
//                        .setContentIntent(pendingIntent)    //pendingIntent to fire when the user taps on it
                .setAutoCancel(true);   //autoremove the notificatin when the user taps on it

        //show the notification constructed above
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(v.getContext());
        notificationManager.notify(NOTIFICATION_ID, builder.build());

        indicator = !indicator; //switch icon indicator (just for demonstration)
    }
});
Hack06
  • 963
  • 1
  • 12
  • 20
  • How would I do that? Please note that I use startForeground() – monok Jun 27 '20 at 09:27
  • Thanks, yet my service status does not change on a button click but it is detected by the service as I described in my question. – monok Jun 27 '20 at 14:08
  • @monok, the button click that I've used is just for demonstration purpose, so you should create a new notification similarly based on the events that you have. – Hack06 Jun 27 '20 at 14:10
2

You only need to hold a reference to the NotificationCompat.Builder. Then use the notify(int id, Notification notification) method of NotificationManagerCompat.

Example:

NotificationCompat.Builder notificationBuilder;

private void startNotif(){
    notificationBuilder = new NotificationCompat.Builder(
        this, NOTE_CHANNEL_ID)
        .setSmallIcon(R.drawable.mute_icon)
        .setContentTitle("Calm: Running")
        .setContentText(this.getString(R.string.calm_close_txt))
        .setOngoing(true)
        .setContentIntent(stopIntent);
    
    startForeground(NOTIFICATION_ID, notificationBuilder.build());
}

private void changeIcon(int resID, Context context){
    notificationBuilder.setSmallIcon(resID);
    NotificationManagerCompat notificationManagerCompat =
                NotificationManagerCompat.from(context);
    notificationManagerCompat.notify(NOTIFICATION_ID, notificationBuilder.build());
}
M D P
  • 4,525
  • 2
  • 23
  • 35