Android Custom Download Service - Providing a progress bar for each file

I would like to be able to show multiple file downloads in the notification panel, which can also be undone.

I have implemented a custom service that runs multiple downloads in parallel using AsyncTasks. OnPublishProgress I'm trying to update individual lines in the notification panel to show the download progress for each file. For two hard days, I tried to fix problems with flickering lines, organizing lines, and sometimes just empty or updating just one line. Also, pressing a line to cancel a procedure does not always work.

Here is my code:

protected void showProgressNotification(final File item, int progress, boolean isDownloading) { String message = null; int smallIcon = 0; Bitmap largeIcon = null; int flags = 0; flags |= Notification.FLAG_ONGOING_EVENT; //flags |= Notification.FLAG_FOREGROUND_SERVICE; //flags |= Notification.FLAG_ONLY_ALERT_ONCE; //flags |= Notification.FLAG_AUTO_CANCEL; NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext()); builder.setAutoCancel(true); if (progress == 100) { largeIcon = BitmapFactory.decodeResource(getResources(), O2FolderListAdapter.getIconForItem(item, false)); smallIcon = R.drawable.ic_cloud_upto_date; if (isDownloading) { message = "Download completed. Tap to clear."; } else { message = "Upload completed. Tap to clear."; } } else if (progress >= 0) { largeIcon = BitmapFactory.decodeResource(getResources(), O2FolderListAdapter.getIconForItem(item, true)); if (isDownloading) { smallIcon = R.drawable.ic_cloud_downloading; message = "Downloading: " + progress + "%. Tap to cancel."; } else { smallIcon = R.drawable.ic_cloud_uploading; message = "Uploading: " + progress + "%. Tap to cancel."; } builder.setProgress(100, progress, false); } else { largeIcon = BitmapFactory.decodeResource(getResources(), O2FolderListAdapter.getIconForItem(item, true)); smallIcon = R.drawable.ic_cloud_conflict; if (isDownloading) message = "Cancelled download. Tap to clear."; else message = "Cancelled upload. Tap to clear."; } if (mResultIntent == null) { mResultIntent = new Intent(getApplicationContext(), CustomDownloadService.class); mResultIntent.addFlags(Notification.FLAG_ONGOING_EVENT); } mResultIntent.putExtra("cancel", item.getPath().hashCode()); Log.d("O2AbstractDownloadService", "Setup task id " + item.GetPath().hashCode()); if (mContentIntent == null) mContentIntent = PendingIntent.getService(getApplicationContext(), PI_REQ_CODE, mResultIntent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(mContentIntent); builder.setLargeIcon(largeIcon); builder.setSmallIcon(smallIcon); builder.setContentTitle(item.GetName()); builder.setContentText(message); //if (progress != 100) //builder.addAction(R.drawable.ic_action_dark_cancel, "Cancel", contentIntent); final Notification notification = builder.build(); notification.flags = flags; notification.defaults = Notification.DEFAULT_LIGHTS; NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Id allows you to update the notification later on. //mNotificationManager.notify(item.getPath().hashCode(), notification); //startForeground(item.getPath().hashCode(), notification); // only update notification every 100ms (unless cancel or complete) long notificationDelay = 100; long now = System.currentTimeMillis(); if (mFutureCallTime == 0 || now > mFutureCallTime || progress == -1 || progress == 100) { startForeground(item.getPath().hashCode(), notification); //mNotificationManager.notify(item.GetPath().hashCode(), notification); } else Log.d("CustomDownloadService", "Called too often to notification"); mFutureCallTime = now + notificationDelay; } 

So, I'm trying to configure the action to invoke the Service when I click on the notification, passing the file ID to cancel the download. Can anyone see what I'm doing wrong? Is that what I'm actually possible? On the Xoom tablet, notifications flicker a lot, but not so often on the Nexus 7. All devices end up changing rows, which means it is almost impossible to cancel the required download.

Any advice is appreciated.

UPDATE 1: I think this may cause one of my problems: Android Service.startForeground DOES NOT respect the uniqueness of the notification identifier

UPDATE 2: The replacement problem has been fixed by calling builder.setWhen (fixedTime). Obviously, the new DateTime caused string reordering every time it was updated. You just need to fix the Xoom flicker and the โ€œTap to Cancelโ€ feature.

UPDATE 3: Flicker on Xoom has been fixed with call restriction for updates. The code at the end prevents the notification from being updated more than once in 100 ms. The remaining problems are related to cancellation. Undo to undo works the first time, but does not work with subsequent files. Also I can not clear the lines.

UPDATE 4: The only cancellation problem was caused by the resultIntent field being at the class level. When I created a new one, every time I updated the notification, the identifiers associated. I also changed the flag only to Notification.FLAG_ONLY_ALERT_ONCE and used only .notify (), not startForeground ().

+6
source share
1 answer

All issues have been fixed. I added updates to my original post. Bottom line: 1) Be careful with builder.setWhen (fixedTime). 2) Do not update more than once every 100 ms 3) Set the correct flags.

+1
source

All Articles