[英]Android DownloadManager Progress
i'm developing an app where users are able to download different content packages.我正在开发一个应用程序,用户可以在其中下载不同的内容包。 For the download process i am using the DownloadManager class.对于下载过程,我使用的是 DownloadManager 类。 Thats working fine so far.到目前为止工作正常。
My Question is how can i get the current progress of a running Download which was started with the DownloadManager.我的问题是如何获取使用 DownloadManager 启动的正在运行的下载的当前进度。 I know that there is the buildin 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 progressbar in my app.但对我来说,我有必要获得正在运行的下载进度,以便我可以使用它在我的应用程序的自定义进度条中显示进度。 So far i was not able to retrieve the progress.到目前为止,我无法检索进度。
Is it even possible or am i just blind and can't find the solution.它甚至可能还是我只是盲目而无法找到解决方案。
Hopefully someone can help me...希望有人可以帮助我...
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.我也在寻找一种更好的方法来做到这一点,但到目前为止,我计划每 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();
Edit:编辑:
A FileObserver
can help with this. FileObserver
可以帮助解决这个问题。 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
.在活动或服务的onStart
启动它并在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.结合onStart
期间事物状态的手动同步,这可以让您对正在发生的事情有一个非常完整的了解。
For progress in particular, watching for the OPEN/CLOSE_WRITE events can help you decide when to start/stop polling the DownloadManager for updates.特别是对于进度,观察 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;
}
}
}
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();
}
}
It turns out that the FileObserver
implementation on Marshmallow has a bug.事实证明,Marshmallow 上的FileObserver
实现有一个错误。 As a result, FileObserver
will not report any modifications of a file downloaded by the download manager.因此, FileObserver
不会报告下载管理器下载的文件的任何修改。 (Older Android versions do not have this issue – it works fine on KitKat.) Source (旧的 Android 版本没有这个问题——它在 KitKat 上运行良好。) 来源
For me, the following code (based on this answer ) works well.对我来说,以下代码(基于此答案)运行良好。 I poll every second – I've tried halving that interval, but without any visible effect.我每秒都进行一次轮询——我曾尝试将该时间间隔减半,但没有任何明显的效果。
private static final int PROGRESS_DELAY = 1000;
Handler handler = new Handler();
private boolean isProgressCheckerRunning = false;
// when the first download starts
startProgressChecker();
// when the last download finishes or the Activity is destroyed
stopProgressChecker();
/**
* Checks download progress.
*/
private void checkProgress() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterByStatus(~(DownloadManager.STATUS_FAILED | DownloadManager.STATUS_SUCCESSFUL));
Cursor cursor = downloadManager.query(query);
if (!cursor.moveToFirst()) {
cursor.close();
return;
}
do {
long reference = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
long progress = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
// do whatever you need with the progress
} while (cursor.moveToNext());
cursor.close();
}
/**
* Starts watching download progress.
*
* This method is safe to call multiple times. Starting an already running progress checker is a no-op.
*/
private void startProgressChecker() {
if (!isProgressCheckerRunning) {
progressChecker.run();
isProgressCheckerRunning = true;
}
}
/**
* Stops watching download progress.
*/
private void stopProgressChecker() {
handler.removeCallbacks(progressChecker);
isProgressCheckerRunning = false;
}
/**
* Checks download progress and updates status, then re-schedules itself.
*/
private Runnable progressChecker = new Runnable() {
@Override
public void run() {
try {
checkProgress();
// manager reference not found. Commenting the code for compilation
//manager.refresh();
} finally {
handler.postDelayed(progressChecker, PROGRESS_DELAY);
}
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.