android的DownloadManager超时

时间:2015-02-28 13:36:39

标签: android android-download-manager

我正在使用android内置DownloadManager从互联网上下载文件。问题是,一旦我排队下载,它会尝试永远下载文件!有没有办法设置下载超时?

2 个答案:

答案 0 :(得分:0)

不幸的是,Android没有采用在DownloadManager中设置超时的解决方案。但事实上,当您处于待处理状态时,可以设置TIMEOUT ClockWake:DownloadManager.STATUS_PENDING

DownloadManager.Query query = null;
    Cursor c = null;
    DownloadManager downloadManager = null;
    downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
    query = new DownloadManager.Query();
     if(query!=null) {
                query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PAUSED|DownloadManager.STATUS_SUCCESSFUL|
                        DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_PENDING);
            } else {
                return;
            }
    c = downloadManager.query(query);
    if(c.moveToFirst()) { 
    int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); 
    switch(status) { 
    case DownloadManager.STATUS_PAUSED: 
    break; 
    case DownloadManager.STATUS_PENDING: 
    //here you can set your TIMEOUT solution
    break; 
    case DownloadManager.STATUS_RUNNING: 
    break; 
    case DownloadManager.STATUS_SUCCESSFUL: 
    break; 
    case DownloadManager.STATUS_FAILED: 
    break; 
    }

答案 1 :(得分:0)

@Sofien Rahmouni Virtuel和@flegare解决方案是好主意,但我会尝试提供一个完整可行的例子。我试图解决这个问题已经有好几个小时了,所以它可以节省一些人的谷歌搜索信息。时间。主要思想是在小型和大型文件发生故障或超时时重试下载过程 - 在6-7MB上测试。首先使用该ID删除下载并调用下载方法。对于STATUS_RUNNING,我调用manageDownloadProcess(urlLink, pathUri, fileName, downloadId);方法recursivley以确保下载完成后会成功。

唯一的问题是,即使必须是STATUS_RUNNING,我也会在第一次检查时得到STATUS_PENDING,并且我实施了一种解决方法来避免这种情况。

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

/**
 * Created by Android Developer on 29.10.2015. Copyright ©
 */
public class DownloadFile {

    private static Context mContext = App.getUniversalContext();//here just get aplication context - I have a static method in App class
    private static DownloadManager downloadManager = (DownloadManager) App.getUniversalContext().getSystemService(Context.DOWNLOAD_SERVICE);
    private static int RETRIES_MAX_NUMBER = 3; //nr of retries
    private static int alreadyRetried;
    private static boolean isEntered = false; 

    public static void downloadFile(String urlLink, String pathUri, String fileName) {
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlLink));
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
        request.setDestinationInExternalPublicDir(pathUri, fileName);
        request.setDescription("System download");
        request.setTitle("ADMINISTRATOR");
        request.setVisibleInDownloadsUi(false);
        request.setNotificationVisibility(2)

        final long downloadId = downloadManager.enqueue(request);
        manageDownloadProcess(urlLink, pathUri, fileName, downloadId);

        App.getUniversalContext().registerReceiver(new BroadcastReceiver() {
            public void onReceive(Context ctxt, Intent intent) {
                if (downloadId == intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID)) {
                    mContext.unregisterReceiver(this);
                    //done use your file
                }
            }
        }, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    /*check for timeout / errors and retry logic*/
    private static void manageDownloadProcess(final String urlLink, final String pathUri, final String fileName, final long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_SUCCESSFUL | DownloadManager.STATUS_PAUSED | DownloadManager.STATUS_RUNNING | DownloadManager.STATUS_FAILED);

        final Cursor cursor = downloadManager.query(query.setFilterById(downloadId));
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (cursor.moveToFirst()) {
                    int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                    switch (status) {

                        /*I introdused 'isEntered' param to eliminate first response from this method
                          * I don't know why but I get STATUS_PENDING always on first run, so this is an ugly workaround*/
                        case DownloadManager.STATUS_PENDING: {
                         Log.d("status", "STATUS_PENDING - timeout");
                            if (isEntered) {
                                if (alreadyRetried < RETRIES_MAX_NUMBER) {
                                    alreadyRetried++;
                                    downloadManager.remove(downloadId);
                                    downloadFile(urlLink, pathUri, fileName);
                                    manageDownloadProcess(urlLink, pathUri, fileName, downloadId);

                                }
                            } else {
                                isEntered = true;
                                manageDownloadProcess(urlLink, pathUri, fileName, downloadId);
                            }
                            break;
                        }

                        case DownloadManager.STATUS_PAUSED: {
                            Log.d("status", "STATUS_PAUSED - error");
                            if (alreadyRetried < RETRIES_MAX_NUMBER) {
                                alreadyRetried++;
                                downloadManager.remove(downloadId);
                                downloadFile(urlLink, pathUri, fileName);
                            }
                            break;
                        }

                        case DownloadManager.STATUS_RUNNING: {
                            Log.d("status", "STATUS_RUNNING - good");
                            manageDownloadProcess(urlLink, pathUri, fileName, downloadId);
                            break;
                        }

                        case DownloadManager.STATUS_SUCCESSFUL: {
                            Log.d("status", "STATUS_SUCCESSFUL - done");
                            break;
                        }

                        case DownloadManager.STATUS_FAILED: {
                            Log.d("status", "STATUS_FAILED - error");
                            if (alreadyRetried < RETRIES_MAX_NUMBER) {
                                alreadyRetried++;
                                downloadManager.remove(downloadId);
                                downloadFile(urlLink, pathUri, fileName);
                            }
                            break;
                        }
                    }
                }
            }
        }, 5000);//do this after 5 sec
    }

}