0

I have created a notification for the music player which works perfectly fine but the problem is that notification doesn't get cleared. It just sticks to my notification panel.

How can I clear my notification when I pause the music or close the app?

  void showNotification(int playPauseBtn){
            Intent intent = new Intent(this, MainActivity.class);
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);

        Intent prevIntent = new Intent(this, NotificationReceiver.class)
                .setAction(ACTION_PREVIOUS);
        PendingIntent prevPending = PendingIntent.getBroadcast(this, 0, prevIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Intent pauseIntent = new Intent(this, NotificationReceiver.class)
                .setAction(ACTION_PLAY);
        PendingIntent  pausePending = PendingIntent.getBroadcast(this, 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Intent nextIntent = new Intent(this, NotificationReceiver.class)
                .setAction(ACTION_NEXT);
        PendingIntent nextPending = PendingIntent.getBroadcast(this, 0, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        byte[] picture = null;
        picture = getAlbumArt(musicFiles.get(position).getPath());
        Bitmap thumb = null;
        if (picture != null){
            thumb = BitmapFactory.decodeByteArray(picture, 0, picture.length);
        }
        else{
            thumb = BitmapFactory.decodeResource(getResources(), R.drawable.musicicon);
        }
        passPosition = position;
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID_2)
                .setSmallIcon(playPauseBtn)
                .setLargeIcon(thumb)
                .setContentTitle(musicFiles.get(position).getTitle())
                .setContentText(musicFiles.get(position).getArtist())
                .addAction(R.drawable.ic_skip_previous, "Previous", prevPending)
                .addAction(playPauseBtn, "Pause", pausePending)
                .addAction(R.drawable.ic_skip_next, "Next", nextPending)
                .setContentIntent(contentIntent)
//                .setAutoCancel(true)
                .setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
                        .setMediaSession(mediaSessionCompat.getSessionToken()))
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setOnlyAlertOnce(true)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .build();
        startForeground(2, notification);
        notificationManager =
                (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(2, notification);
    }
Thapakaji
  • 3
  • 2

3 Answers3

0

This example I wrote is a simple notification that is played by clicking the song button and by clicking the stop button the music is cut off and the notification is deleted. Now you see this example and then you can give it a button as you wish.

put this code in your Activity/fragment;

    public void getNotification(){
    
    int notifId =new Random().nextInt(500);   //get random id
    NotificationManager notificationManager;
    Notification notification;
    notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        channelID = "1";
        channelName = "news";
        channelDesc = "news description";
        NotificationChannel notificationChannel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
        notificationChannel.setDescription(channelDesc);
        notificationChannel.enableLights(true);
        notificationChannel.setSound(null, null);
        notificationChannel.setLightColor(Color.GREEN);
        notificationManager.createNotificationChannel(notificationChannel);

    }

    RingtoneManager.getRingtone(mContext,
            RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)).play();

    NotificationCompat.Builder   builder = new NotificationCompat.Builder(mContext, channelID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("title Of MUSIC")
            .setContentText("Content")
            .setVibrate(new long[]{100, 500, 500, 500, 500})
            .setAutoCancel(true)
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
            .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher))
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);

    Intent actionReadMessage = new Intent(mContext, NotifAction.class);
    actionReadMessage.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    actionReadMessage.setAction("Play");
   actionReadMessage.putExtra("NotifId",notifId);
    PendingIntent playPendingIntent = PendingIntent.getBroadcast(mContext, notifId, actionReadMessage,PendingIntent.FLAG_CANCEL_CURRENT);




    Intent mainAction = new Intent(mContext, NotifAction.class);
    mainAction.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    mainAction.setAction("Pause");
    mainAction.putExtra("NotifId",notifId);
    PendingIntent PausePendingIntent = PendingIntent.getBroadcast(mContext, notifId, mainAction,PendingIntent.FLAG_CANCEL_CURRENT);

    

    builder.setContentIntent(PausePendingIntent);
    builder.addAction(R.mipmap.ic_launcher, "Play", playPendingIntent);
    builder.addAction(R.mipmap.ic_launcher, "Pause", PausePendingIntent);
    
    notification = builder.build();
    notificationManager.notify(notifId,  notification);
    

    }

and create class NotifAction.class for handle all action:

public class NotifAction extends BroadcastReceiver {

private static final String TAG = "maybe";
private MediaPlayer mp;
@Override
public void onReceive(final Context context, Intent intent) {

    String action = intent.getAction();
    Bundle extra = intent.getExtras();

    if (extra != null) {
        int notifId = extra.getInt("NotifId");
        if (action.equals("Play")) {
            mp = MediaPlayer.create(context, R.raw.music);
            handleMusicState(mp);
        } else if (action.equals("Pause")) {

            handleMusicState(mp);
            setMessageRead(notifId, context);

        } else {
            Toast.makeText(context, "extra  action !", Toast.LENGTH_SHORT).show();
        }

    } else {
        Toast.makeText(context, "Empty extra !", Toast.LENGTH_SHORT).show();
    }
    }


private void setMessageRead(int id, Context context) {
    //  other  method
    clearNotification(id, context);

   }

private void clearNotification(int id, Context context) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancel(id);
   }

private void handleMusicState(MediaPlayer mediaPlayer) {
    if (mediaPlayer.isPlaying()) mediaPlayer.pause();
    else mediaPlayer.start();

    }
   }

define this receiver to manifest: note:in tag

 <receiver android:name=".NotifAction">
        <intent-filter>
            <action android:name="Play" />
            <action android:name="Pause" />
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>
  • Thank you for your answer. I have found a quite easier and short way to do that in here: https://stackoverflow.com/a/35721582 – Thapakaji Jul 19 '21 at 07:59
0

I am answering because it may help someone and save their time for this simple question which took me hours to figure it out.
I had started the foreground service startForeground(id, notification); which was keeping my notification sticky and not clearable. Using stopForeground(false); solved my problem. For further more detailed answer you can check it out at: https://stackoverflow.com/a/35721582

Thapakaji
  • 3
  • 2
0

If you're using a Service, you have to cancel notification when overriding onDestroy.

override fun onDestroy() {
    (context.getSystemService(Context.NOTIFICATION_SERVICE) as 
    NotificationManager).cancel(notificationId)
    stopForeground(true)
    super.onDestroy()
}
Maede Jalali
  • 306
  • 2
  • 6