I have a Service
that facilitates the downloading of files from a server. Everytime an Intent
is received in onStartCommand
, I start a new Thread
, put the Thread
into a map with the url being downloaded as the key, and create a notification to show the progress of the download. If there are no Thread
s in the map, a flag is set in the Thread
that signifies that it should use startForeground
when the Notification
is being created or updated. Subsequent Thread
s/Notification
s are show using NotificationManager.notify
with the FLAG_AUTO_CANCEL
off and the FLAG_ONGOING_EVENT
on. Each Thread
has its own unique id that is sent to startForeground
or notify
. When the file is finished downloading, or the user cancels the download (by pressing a button in the Notification
's RemoteView
, if it is the "foreground thread/notification," stopForeground(true)
is called, the Notification
is populated with a new RemoteView
that shows whether the download completed or not, and the next running Thread
has its "foreground" flag set to true
.
The problem is, if I have, let's say, two files downloading, there will be one Notification
/Thread
that is connected to startForeground
and one that is not. If I cancel the "foreground" one, everything is fine. However, if I press the cancel button on the non-foreground one, the foreground one is dismissed (and pressing the cancel button again will then dismiss the proper one). If I don't cancel any, and I start a 3rd download that completes before the others, the completed Notification
shows, but the other two that are still going start to blink and rapidly move up and down in the status bar.
How do I make sure that the Service
will always be in the foreground as long as there are downloads going on, without the notifications jumping around in the situation noted above, and with the cancelling working properly?
What I ended up doing was making a variable in the Service
called isInForeground
that is global to all of the Thread
s. It signifies whether startForeground
has been called, without a subsequent call to stopForeground
.
In my updateNotification
method, I check isInForeground
. If it is false
I set it to true
, set the Thread
's isForegroundNotification
flag to true
, and call startForeground
with that Thread
's Notification
. In my stopNotification
method, if the Thread
's isForegroundNotification
is true
, I set it and isInForeground
to false
and call stopForeground(true)
.