Android DownloadManager进度

use*_*622 39 android download-manager

我正在开发一个应用程序,用户可以下载不同的内容包.对于下载过程,我使用的是DownloadManager类.那个到目前为止工作正常.

我的问题是如何获得使用DownloadManager启动的正在运行的下载的当前进度.我知道有buildin下载通知等等.但对我来说,我必须获得正在运行的下载的进度,以便我可以使用它来显示我的应用程序中自定义进度条的进度.到目前为止,我无法检索进度.

它是否可能,或者我只是盲目而无法找到解决方案.

希望有人可以帮助我......

dok*_*ebi 37

我正在寻找一种更好的方法来做到这一点,但到目前为止,我计划每1秒左右轮询一次进展.

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();
Run Code Online (Sandbox Code Playgroud)

编辑:

A FileObserver可以帮助解决这个问题.这是我整理的一个框架,以帮助跟踪我们的应用程序下载了哪些文件.在活动或服务中启动它onStart并将其停止onStop.结合手动同步状态onStart,这可以让您完整了解正在发生的事情.

特别是进度,观察OPEN/CLOSE_WRITE事件可以帮助您决定何时开始/停止轮询DownloadManager以获取更新.

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对我很有用!但是请记住,`FileObserver#onEvent()` 在单独的线程上运行。对于任何 UI 操作(例如更新进度条),您需要执行类似 `new Handler(Looper.getMainLooper()).post(new Runnable() {...});` 之类的操作,并将代码放在`Runnable` 的 `run()` 方法。 (2认同)
  • 修订:在KitKat **上效果很好,但在棉花糖**上效果不佳。根据http://stackoverflow.com/questions/32354489/fileobserver-does-not-work-on-external-storage-in-android-6-0-marshmallow-api-2的说法,这似乎是棉花糖中的错误... (2认同)