【问题标题】:timeout for android DownloadManager安卓下载管理器超时
【发布时间】:2015-02-28 13:36:39
【问题描述】:

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

【问题讨论】:

    标签: android android-download-manager


    【解决方案1】:

    @Sofien Rahmouni Virtuel 和@flegare 解决方案是好主意,但我会尝试给出一个完整的可行示例。我试图解决这个问题花了更多时间,所以它可以节省某人的“谷歌搜索”时间。主要思想是在大小文件失败或超时时重试下载过程 - 在 6-7MB 上进行测试。首先删除具有该 ID 的下载并调用下载方法。对于 STATUS_RUNNING,我调用 manageDownloadProcess(urlLink, pathUri, fileName, downloadId); 方法 recursivley 以确保下载成功完成。

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

    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
        }
    
    }
    

    【讨论】:

    • 对我来说,有时即使是无效的 url,下载也处于 RUNNING 状态...我通过更改逻辑来解决,以检查在没有下载任何字节的情况下停留了多少时间
    【解决方案2】:

    不幸的是,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; 
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 2014-02-23
      • 2012-10-31
      • 2010-12-19
      • 2012-02-29
      • 2016-05-25
      相关资源
      最近更新 更多