2

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)

    }
Ahmad ElMadi
  • 2,507
  • 21
  • 36
  • "as we know that such services need a notification to keep running" - that is not a requirement in Android 13. What makes you think it is? – ianhanniballake Feb 24 '23 at 22:46
  • 1
    @ianhanniballake first line in the documentation "Foreground services perform operations that are noticeable to the user. Foreground services show a status bar notification, to make users aware that your app is performing a task in the foreground and is consuming system resources." – Ahmad ElMadi Feb 24 '23 at 22:48
  • @AhmadElMadi Please refer to this answer and check if this is working for you. [Prevent user from dismissing notification](https://stackoverflow.com/a/18464841/2576595) Also there is a bug on android 13 about this. They say's it will be fixed in future updates. [Able to dismiss foreground service notification on android 13](https://issuetracker.google.com/issues/237894785) – Quimbo Feb 24 '23 at 22:50
  • @Quimbo I just did , but no use . I still can dismiss it . Edited the snippit above. – Ahmad ElMadi Feb 24 '23 at 23:05
  • @Quimbo Thanks , I hope they will fix it soon . – Ahmad ElMadi Feb 25 '23 at 00:41

2 Answers2

1

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();
Rob
  • 518
  • 1
  • 3
  • 18
  • Sorry, just realized the while loop should go inside the thread, otherwise it'll try to generate a bunch of new threads. Updated. – Rob Feb 25 '23 at 21:17
  • Thanks, but would it run after killing the app and dismiss the notification , I am not so confident with Android apps lifecycle – Ahmad ElMadi Feb 26 '23 at 18:08
  • Right, so you will have to send a broadcast from your app to the service with the kill switch if the user stops the app. The main activity in the app will send a broadcast with the kill switch, and the service activity will have a broadcast receiver that listens for the kill switch. See [Broadcasts overview](https://developer.android.com/guide/components/broadcasts) for more info. There are a number of good tutorials online as well. Good luck! – Rob Feb 26 '23 at 21:38
  • 1
    Hi Rob , thanks for your help , but i think i found the issue. The problem was that I did not set the small icon for the notification . once that is set then its all good . one thing though , the icon seems too small though . – Ahmad ElMadi Feb 26 '23 at 23:48
  • Nice, well that's a much easier fix than what I thought you'd have to do! Interesting that the icon was the issue. – Rob Feb 27 '23 at 03:39
0

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 .

Ahmad ElMadi
  • 2,507
  • 21
  • 36