Android 13: User can dismiss notification even after setting "setOnGoing(true)"

1.8k views Asked by At

I am making a foreground service and as we know that such services need a notification to keep running. However since Android 13, the user can dismiss it just by swiping, thus the app is killed.

I tried to use setOnGoing(true) on the notification builder but no use.

I need to make the notification non-dismissable.

This is my code in Kotlin .

      private fun startForegroundServiceWithNotification() {
        Log.d("myTag", "startForegroundServiceWithNotification")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelId = CHANNEL_ID
            val channelName = "Wish2Go step counter"
            val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
            val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            service.createNotificationChannel(chan)
        }


        var builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setOngoing(true)
            .setContentTitle("Counting steps")
            .setPriority(NotificationCompat.PRIORITY_HIGH)

        var notification = builder.build()
        notification.flags = Notification.FLAG_ONGOING_EVENT
        startForeground(1001, notification)

    }
2

There are 2 answers

0
Ahmad ElMadi On BEST ANSWER

I found the issue i had, apparently that i forgot to set the smallIcon for my notification

private fun startForegroundServiceWithNotification() {
    Log.d("myTag", "startForegroundServiceWithNotification")
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channelId = CHANNEL_ID
        val channelName = "Wish2Go step counter"
        val chan = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
        val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        service.createNotificationChannel(chan)
    }


    var builder = NotificationCompat.Builder(this, CHANNEL_ID)
        .setOngoing(true)
        .setContentTitle("Counting steps")
        .setContentText("Open the app to see how are you doing.")
        .setSmallIcon(R.mipmap.ic_launcher_round) //Missing this was the issue 
        .setPriority(NotificationCompat.PRIORITY_HIGH)

    var notification = builder.build()
    notification.flags = Notification.FLAG_ONGOING_EVENT
    startForeground(1001, notification)

}

After setting the small Icon the notification acted as expected .

5
Rob On

I have a similar foreground service in an app I made. In my app, I update the notification every second using a timer, because my app displays a countdown timer as part of the notification. If the user has dismissed the notification, it reappears after one second. Maybe you can try something similar with your app.

I'd try creating a thread with an infinite loop that sleeps for one second and then refreshes the notification. This is in Java, but you get the idea.

// init and build notification, same as before 
notification = builder.build();

// create a notification manager
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

// infinite loop with a 'kill switch' for when the user manually stops the service from the app
new Thread(new Runnable() {
    @Override
    public void run() {
        while(!killSwitch) {
            try {
                Thread.sleep(1000);  // sleep for one second

                /* make sure the first parameter here matches the id you defined when 
                   you initialized the notification */
                notificationManager.notify(1001, builder.build());

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}).start();