I'm developing an app where users are able to download different content packages. For the download process, I'm using the DownloadManager
class. That's working fine so far.
How can I get the current progress of a running download which was started with the DownloadManager
. I know that there is the builtin Download Notification and so on, but for me it is necessary that I get the progress of the running download so I can use it to show the progress in a custom progress bar in my app.
Is it even possible or am I just blind and can't find the solution.
I am looking for a better way of doing this also, but so far I am planning to just poll for progress every 1sec or so.
DownloadManager mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); long id = mgr.enqueue(request); DownloadManager.Query q = new DownloadManager.Query(); q.setFilterById(id); Cursor cursor = mgr.query(q); cursor.moveToFirst(); int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); cursor.close();
Edit:
A FileObserver
can help with this. This is the skeleton of one I have put together to help keep track of which files our app has downloaded. Start it in an activity or service's onStart
and stop it in onStop
. Combined with a manual synchronization of the state of things during onStart
, this can give you a pretty complete picture of what's going on.
For progress in particular, watching for the OPEN/CLOSE_WRITE events can help you decide when to start/stop polling the DownloadManager for updates.
public class DownloadsObserver extends FileObserver { public static final String LOG_TAG = DownloadsObserver.class.getSimpleName(); private static final int flags = FileObserver.CLOSE_WRITE | FileObserver.OPEN | FileObserver.MODIFY | FileObserver.DELETE | FileObserver.MOVED_FROM; // Received three of these after the delete event while deleting a video through a separate file manager app: // 01-16 15:52:27.627: D/APP(4316): DownloadsObserver: onEvent(1073741856, null) public DownloadsObserver(String path) { super(path, flags); } @Override public void onEvent(int event, String path) { Log.d(LOG_TAG, "onEvent(" + event + ", " + path + ")"); if (path == null) { return; } switch (event) { case FileObserver.CLOSE_WRITE: // Download complete, or paused when wifi is disconnected. Possibly reported more than once in a row. // Useful for noticing when a download has been paused. For completions, register a receiver for // DownloadManager.ACTION_DOWNLOAD_COMPLETE. break; case FileObserver.OPEN: // Called for both read and write modes. // Useful for noticing a download has been started or resumed. break; case FileObserver.DELETE: case FileObserver.MOVED_FROM: // These might come in handy for obvious reasons. break; case FileObserver.MODIFY: // Called very frequently while a download is ongoing (~1 per ms). // This could be used to trigger a progress update, but that should probably be done less often than this. break; } } }
Usage would be something like this:
public class MyActivity extends Activity { private FileObserver fileObserver = new DownloadsObserver( getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()); @Override protected void onStart() { super.onStart(); fileObserver.startWatching(); syncUpDatabaseWithFileSystem(); } @Override protected void onStop() { fileObserver.stopWatching(); super.onStop(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With