Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a notification from a foreground service cancelable once the service is not in foreground anymore

I have a music control notification that allows the user to start/stop the music. I want exactly the same behavior than the Google Play Music app notification: when music is playing, the service is in foreground and the notification not cancelable, and when the music is not playing the service is not in the foreground anymore and the notification can be removed. It works fine but when I cancel the foreground of my service, the notification is quickly removed before reappearing just after.

Here's my code, first how I build the notification:

NotificationCompat.Builder notifBuilder =
            new android.support.v7.app.NotificationCompat.Builder(getApplicationContext())
                    .setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
                            .setShowActionsInCompactView(1, 2, 3)
                            .setShowCancelButton(true)
                            .setCancelButtonIntent(deletePendingIntent)))
                    .setSmallIcon(R.drawable.notif_logo)
                    .setColor(ResourcesCompat.getColor(getResources(), R.color.blue, getTheme()))
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setShowWhen(false);

    notifBuilder.setContentIntent(pendingIntent);
    notifBuilder.setDeleteIntent(deletePendingIntent);

And here is how I start and update my notification:

private void showNotification(NotificationCompat.Builder notifBuilder, boolean foreground) {
    if (foreground) {
        startForeground(NOTIFICATION_ID, notifBuilder.build());
    } else {
        stopForeground(false);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID, notifBuilder.build());
    }
}

If I use stopForeground(false), the notification is still not cancelable after running it. If I use stopForeground(true), the notification is quickly removed then added again which give a weird blinking.

How can I have a notification that is cancelable after a service quit being in foreground, without having to remove then add again the notification?

like image 702
MickaelG Avatar asked Mar 10 '23 06:03

MickaelG


1 Answers

Per the Using MediaStyle notifications with a foreground service documentation:

In Android 5.0 (API level 21) and later you can swipe away a notification to stop the player once the service is no longer running in the foreground. You can't do this in earlier versions. To allow users to remove the notification and stop playback before Android 5.0 (API level 21), you can add a cancel button in the upper-right corner of the notification by calling setShowCancelButton(true) and setCancelButtonIntent().

You never need to call setOngoing(false)/setOngoing(true) as that is controlled by whether your service is currently in the foreground.

As per the Media Session Callbacks docs, you should be called stopForeground(false) when your music gets paused - this remove the foreground priority and allows users to swipe the notification away on API 21+ devices.

like image 135
ianhanniballake Avatar answered Apr 25 '23 11:04

ianhanniballake