我需要跟踪多个文件的下载。经过大量的思考和实验,我想出了以下代码:
private void startDownloadThread(final List<DownloadFile> list) {
// Initializing the broadcast receiver ...
mBroadCastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mFinishedFilesFromNotif.add(intent.getExtras()
.getLong(DownloadManager.EXTRA_DOWNLOAD_ID));
}
};
IntentFilter intentFilter = new IntentFilter(
"android.intent.action.DOWNLOAD_COMPLETE");
DownloadProgressUIFragment.this.getActivity().registerReceiver(mBroadCastReceiver,
intentFilter);
// initializing the download manager instance ....
mDownloadManager = (DownloadManager) getActivity()
.getSystemService(Context.DOWNLOAD_SERVICE);
// adding files to the download manager list ...
for(DownloadFile f: list) {
mDownloadIds.add(FileUtils.addFileForDownloadInBkg(getApplicationContext(),
f.getUrl(),
f.getPath()));
}
// starting the thread to track the progress of the download ..
mProgressThread = new Thread(new Runnable() {
@Override
public void run() {
// Preparing the query for the download manager ...
DownloadManager.Query q = new DownloadManager.Query();
long[] ids = new long[mDownloadIds.size()];
final List<Long> idsArrList= new ArrayList<>();
int i = 0;
for (Long id: mDownloadIds) {
ids[i++] = id;
idsArrList.add(id);
}
q.setFilterById(ids);
// getting the total size of the data ...
Cursor c;
while(true) {
// check if the downloads are already completed ...
// Here I have created a set of download ids from download manager to keep
// track of all the files that are dowloaded, which I populate by creating
//
if(mFinishedFilesFromNotif.containsAll(idsArrList)) {
isDownloadSuccess = true;
// TODO - Take appropriate action. Download is finished successfully
return;
}
// start iterating and noting progress ..
c = mDownloadManager.query(q);
if(c != null) {
int filesDownloaded = 0;
float fileFracs = 0f; // this stores the fraction of all the files in
// download
final int columnTotalSize = c.getColumnIndex
(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
final int columnStatus = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
//final int columnId = c.getColumnIndex(DownloadManager.COLUMN_ID);
final int columnDwnldSoFar =
c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
while (c.moveToNext()) {
// checking the progress ..
if(c.getInt(columnStatus) == DownloadManager.STATUS_SUCCESSFUL) {
filesDownloaded++;
}
// If the file is partially downloaded, take its fraction ..
else if(c.getInt(columnTotalSize) > 0) {
fileFracs += ((c.getInt(columnDwnldSoFar) * 1.0f) /
c.getInt(columnTotalSize));
} else if(c.getInt(columnStatus) == DownloadManager.STATUS_FAILED) {
// TODO - Take appropriate action. Error in downloading one of the
// files.
return;
}
}
c.close();
// calculate the progress to show ...
float progress = (filesDownloaded + fileFracs)/ids.length;
// setting the progress text and bar...
final int percentage = Math.round(progress * 100.0f);
final String txt = "Loading ... " + percentage + "%";
// Show the progress appropriately ...
}
}
}
});
mProgressThread.start();
}
入队文件的功能是:
public static long addFileForDownloadInBkg(Context context, String url, String savePath) {
Uri uri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
request.setDestinationUri(Uri.fromFile(new File(savePath)));
final DownloadManager m = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
return m.enqueue(request);
}
基本上,我会为每个已完成下载的文件单独收到通知,然后将它们添加到一个集合中,该集合基本上是帮助我确定所有下载是否已完成的集合。我根据文件的数量和每个文件完成的比例来跟踪进度。我希望这有帮助。