通过互联网实现下载文件的简历

时间:2017-07-26 10:25:17

标签: java android downloading

我下面的代码下载文件工作正常时没有实现resume,在阅读了更多解决方案来实现并解决问题我知道我必须检查Last-Modified标头并设置它用于连接,

但我无法做到这一点,因为我收到android Cannot set request property after connection is madenull的{​​{1}}错误,

我正在使用此reference

httpURLConnection heaser返回:

getHeaderField

现在我如何设置恢复下载文件?

GitHub Link

{
  null=[HTTP/1.1 200 OK], 
  Cache-Control=[public], 
  Connection=[keep-alive], 
  Content-Length=[8037404], 
  Content-Md5=[VEqXHCc/Off7a6D0gRFpiQ==], 
  Content-Type=[image/jpeg], 
  Date=[Tue, 19 Jan 2016 07:24:36 GMT], 
  Etag=["544a971c273f39f7fb6ba0f481116989"], 
  Expires=[Sat, 29 Jul 2017 10:07:00 GMT], 
  Last-Modified=[Thu, 18 Dec 2014 08:44:34 GMT], 
  Server=[bws], 
  X-Android-Received-Millis=[1501063623576], 
  X-Android-Response-Source=[NETWORK 200], 
  X-Android-Selected-Protocol=[http/1.1], 
  X-Android-Sent-Millis=[1501063623532]
}

我还得到public void run() { final URL url; HttpURLConnection httpURLConnection = null; try { try { url = new URL(mUrl); String lastModified = httpURLConnection.getHeaderField("Last-Modified"); if (!lastModified.isEmpty()) { httpURLConnection.setRequestProperty("If-Range", lastModified); } httpURLConnection = (HttpURLConnection) url.openConnection(); if (mFile.exists()) { downloadedLength = mFile.length(); Log.e("downloadedLength ", downloadedLength + ""); httpURLConnection.setRequestProperty("Range", "bytes=" + downloadedLength + "-"); fileOutputStream = new FileOutputStream(mFile, true); } else { fileOutputStream = new FileOutputStream(mFile); } httpURLConnection.setConnectTimeout(30000); httpURLConnection.setReadTimeout(30000); httpURLConnection.setRequestMethod("GET"); } catch (IOException e) { } final int responseCode; final int total; try { responseCode = httpURLConnection.getResponseCode(); total = httpURLConnection.getContentLength(); } catch (IOException e) { e.printStackTrace(); Log.e("ER UPDATE ", e.getMessage()); } if (responseCode == 200) { try { inputStream = httpURLConnection.getInputStream(); } catch (IOException e) { e.printStackTrace(); Log.e("IOException ", e.getMessage()); } final byte[] buffer = new byte[4 * 1024]; int length = -1; int finished = 0; long start = System.currentTimeMillis(); try { while ((length = inputStream.read(buffer)) != -1) { if (!isDownloading()) { throw new CanceledException("canceled"); } fileOutputStream.write(buffer, 0, length); finished += length; if (System.currentTimeMillis() - start > 1000) { onDownloadProgressing(finished, total); start = System.currentTimeMillis(); } } onDownloadCompleted(); } catch (IOException e) { e.printStackTrace(); Log.e("ER UPDATE ", e.getMessage()); } } else { Log.e("responseCode ", responseCode + ""); } } catch (DownloadException e) { e.printStackTrace(); Log.e("ER UPDATE ", e.getMessage()); } catch (CanceledException e) { e.printStackTrace(); Log.e("ER UPDATE ", e.getMessage()); } } 响应代码,而不是206

2 个答案:

答案 0 :(得分:5)

1- httpURLConnection为空,因为您在初始化之前尝试调用它,

即,这一行

httpURLConnection = (HttpURLConnection) url.openConnection();

应该在这一行之前:

String lastModified = httpURLConnection.getHeaderField("Last-Modified");

2-您可以在connect()上致电httpURLConnection之前设置标头 所以你需要设置你想要的任何东西,然后连接()。这样你不应该得到错误(android连接后无法设置请求属性)

3- 206 perfectly right,这是Range使用httpURLConnection.setRequestProperty("If-Range", lastModified); 时的含义,表示部分内容成功< / strong>以及您正在做的事情,您正在获取部分内容,如果您获得完整内容,您将获得 200

总而言之,您的代码可能如下所示: 注意:按照// ***查看所需的更改。

编辑:这一切都来到了这一行

public void run() {
    myLastModified = getLastModified(mFile.getName()); // get last stored value for this file (use file name or other key)
    int total =0;

    final URL         url;
    HttpURLConnection httpURLConnection = null;
    try {
        try {
            url = new URL(mUrl);

            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setDoInput(true);

            httpURLConnection.setConnectTimeout(30000);
            httpURLConnection.setReadTimeout(30000);
            httpURLConnection.setRequestMethod("GET");

            //*** new way to handle download process
            total = httpURLConnection.getContentLength();
            if(mFile.exists()){
                if(mFile.length() == total){
                    //we are done, return.
                    return;
                }else{
                    //file was not completly donwloaded, now check lastModified:
                    long lastModified = httpURLConnection.getLastModified();//this gets the header "Last-Modified" and convert to long
                    if (lastModified == myLastModified) { //myLastModified should be retrived on each download and stored locally on ur system
                        downloadedLength = mFile.length();
                        Log.e("downloadedLength ", downloadedLength + "");
                        httpURLConnection = (HttpURLConnection) url.openConnection();
                        httpURLConnection.setDoInput(true);

                        httpURLConnection.setConnectTimeout(30000);
                        httpURLConnection.setReadTimeout(30000);
                        httpURLConnection.setRequestMethod("GET");

                        httpURLConnection.setRequestProperty("Range", "bytes=" + downloadedLength + "-"+ total); //add + total (TO)

                        //append mode
                        fileOutputStream = new FileOutputStream(mFile, true);
                    }else{
                        //file was modified after 1st uncompleted-download:
                        storeLastModified(lastModified, mFile.getName()); // use file name as key. can store in db or file ...

                        //don't set ant Range ... we want full download, with a fresh file
                        fileOutputStream = new FileOutputStream(mFile);
                    }//last mod IF

                }//Length check
            }else{
                //file not exist at all, create new file, set no Range we want full download...
                mFile.createNewFile();
                fileOutputStream = new FileOutputStream(mFile);
            }//file exists.

        } catch (IOException e) {
            e.printStackTrace();
        }
        final int responseCode;

        try {
            responseCode = httpURLConnection.getResponseCode();

        } catch (IOException e) {
            e.printStackTrace();
            Log.e("ER UPDATE ", e.getMessage());
        }

        //*****
        if (responseCode == 200 || responseCode == 206) {
            try {
                inputStream = httpURLConnection.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("IOException ", e.getMessage());
            }
            final byte[] buffer   = new byte[4 * 1024];
            int          length   = -1;
            int          finished = 0;
            long         start    = System.currentTimeMillis();
            try {
                while ((length = inputStream.read(buffer)) != -1) {
                    if (!isDownloading()) {
                        throw new CanceledException("canceled");
                    }
                    fileOutputStream.write(buffer, 0, length);
                    finished += length;
                    if (System.currentTimeMillis() - start > 1000) {
                        onDownloadProgressing(finished, total);
                        start = System.currentTimeMillis();
                    }
                }
                onDownloadCompleted();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("ER UPDATE ", e.getMessage());
            }
        } else {
            Log.e("responseCode ", responseCode + "");
        }
    } catch (DownloadException e) {
        e.printStackTrace();
        Log.e("ER UPDATE ", e.getMessage());
    } catch (CanceledException e) {
        e.printStackTrace();
        Log.e("ER UPDATE ", e.getMessage());
    }
}

设置该属性时会抛出错误,

无论如何,当你看到这个,它没有意义时,你会问最后修改是否等于你从连接中得到的值! 如果你想这样做,你需要在你的系统中存储 lastModified , 然后将它与您从URLConn获得的那个进行比较,并将其与您的文件长度(已下载)进行比较 然后继续完整下载或继续下载。

在下面找到新代码:

for ($i=0; $i <2 ; $i++) { //two sheet create excel workbook

      $newsheet = $objPHPExcel->createSheet();//sheet create 

      $newsheet->setTitle("week". $i); //sheet  name use looping

}

答案 1 :(得分:1)

查看thisPOMATu回答。 但无论如何,如果您通过HTTP协议下载文件,您可以使用DownloadManager - 系统服务(自API级别9),以便在后台长时间运行下载。它处理HTTP连接,连接更改,重新启动,并确保每次下载成功完成。它已经支持恢复并且还会提前通知。

您可以找到许多教程,例如thisthat等示例,以及stackoverflow标记上的许多解决方案。