I have an IntentService that uploads a file. Everything works fine, but I'm a little confused about how to handle the notifications. When I start the notification I use startForeground()
because the files can be rather large and I don't want the upload to get killed unless absolutely necessary. When I use startForeground()
it displays two notifications in the notification area (one under Ongoing and one under Notifications):

I've read through a number of different Stack Overflow posts and web articles, but none of them answer the question I have...hopefully I haven't missed one that talks about ths.
It's my understanding that the ongoing notification in the image above (the one without the progress bar) is put there since this is running in the foreground (Services documentation). That's all well and good if you ask me, and I understand why. However, I don't need two notifications displayed and I'm pretty sure most people wouldn't want two notifications cluttering up the notification area either. I would like to know how to properly handle the notification so that only one displays and doesn't clutter up the notification area.
The only way I've been able to get around this is if I set the integer ID for startForeground (int id, Notification notification)
(ONGOING_NOTIFICATION_ID
in my code below) to zero. However, the documentation I quote above says:
Caution: The integer ID you give to startForeground() must not be 0
Setting it to 0 disables the Ongoing notification and then just shows the regular notification with the progress bar. I figure I could kind of "fix" this by setting .setOngoing(true)
until it's done uploading the file and then setting .setOngoing(false)
once it's finished, so it can be dismissed. I'm not sure exactly how "Cautious" one has to be with setting the integer ID to 0. To me it kind of seems like a lazy way to be able to get around the issue I'm having, but I don't know if there are other consequences for setting it to 0. Also, this only works if I only have one notification that I'm dealing with. If I have multiple, different notifications, then I'll need different IDs for each one and this won't work. Update: It looks like setting the ID to 0 won't work in Android 4.3, so now I'm back to square one.
What is a valid way to get around displaying both notifications?
Update/Solution: Duh, taking some time off and then coming back to this and double-checking what I had done based on @dsandler 's recommendation helped me figure out what I was doing wrong. I wasn't setting the correct ID when I was doing the progress update, so that's why it was creating two notifications and one wasn't getting updated. Using the same ID (ONGOING_NOTIFICATION_ID) for all the notifications solved the issue for me. See the code below for the additional pieces I hadn't included before and where I had made the mistake.
Relevant code from UploadFile.java:
public class UploadFile extends IntentService { private static final int ONGOING_NOTIFICATION_ID = 1; @Override protected void onHandleIntent(Intent intent) { mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mBuilder = new NotificationCompat.Builder(this); mBuilder.setContentTitle(getText(R.string.upload)) .setContentText("0% " + getText(R.string.upload_in_progress)) .setSmallIcon(android.R.drawable.stat_sys_upload); startForeground(ONGOING_NOTIFICATION_ID, mBuilder.build()); .... if (progress > 0){ percent = (Long.valueOf(progress) * 100) / totalSize; mBuilder.setProgress(100, percent.intValue(), false); mBuilder.setContentText(percent.intValue() + "% " + getText(R.string.upload_in_progress)); mNotifyManager.notify(ONGOING_NOTIFICATION_ID, mBuilder.build()); // <-- My problem was that I had set the ID here to 0 and did not make it the same as the ID I set above } .... }
First off, judging by your description, you might be able to get away with a regular service, recognizing that the out-of-memory killer won't come calling unless things are getting dire on the device and your service has really been running a very long time.
That said, if you must make the service foreground, the typical strategy here is to show your progress using the Notification you used when you put your service into the foreground state. Using NotificationManager.notify
you can post as many updates to that notification as you like, including adjustments to progress bars via Notification.Builder.setProgress
, for example.
In this way you only show one notification to the user, and it's the one required by startForeground
.
When you want to update a Notification set by startForeground(), simply build a new notication and then use NotificationManager to notify it.
The KEY point is to use the same notification id.
I didn't test the scenario of repeatedly calling startForeground() to update the Notification, but I think that using NotificationManager.notify would be better.
Updating the Notification will NOT remove the Service from the foreground status (this can be done only by calling stopForground );
Example:
private static final int notif_id=1; @Override public void onCreate (){ this.startForeground(); } private void startForeground() { startForeground(notif_id, getMyActivityNotification("")); } private Notification getMyActivityNotification(String text){ // The PendingIntent to launch our activity if the user selects // this notification CharSequence title = getText(R.string.title_activity); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyActivity.class), 0); return new Notification.Builder(this) .setContentTitle(title) .setContentText(text) .setSmallIcon(R.drawable.ic_launcher_b3) .setContentIntent(contentIntent).getNotification(); } /** this is the method that can be called to update the Notification */ private void updateNotification() { String text = "Some text that will update the notification"; Notification notification = getMyActivityNotification(text); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(notif_id, notification); }
来源:https://stackoverflow.com/questions/18029431/how-to-correctly-handle-startforegrounds-two-notifications