Реализация резюме для загрузки файлов через интернет

мой нижеприведенный код для загрузки файла отлично работает, когда не реализует resume для этого, после того как вы прочитали больше решений для реализации и устранения проблемы, я знаю, что я должен проверить заголовок Last-Modified и установить его для соединения,

но я не могу этого сделать из-за того, что я получаю ошибку, например android Cannot set request property after connection is made, или я получаю null для httpURLConnection,

Я использую эту ссылку

getHeaderField Возврат лайнера:

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

Теперь, как я могу установить, что есть для загрузки файлов?

Ссылка GitHub

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 вместо 200

Ответ 1

1- Вы получаете null для httpURLConnection, потому что вы пытаетесь вызвать его перед инициализацией,

i.e, эта линия

httpURLConnection = (HttpURLConnection) url.openConnection();

должен появиться перед этой строкой:

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

2- вы можете установить заголовок перед вызовом connect() на httpURLConnection поэтому вам нужно установить все, что захотите, а затем connect(). таким образом, вы не должны получать ошибку (андроид не может установить свойство запроса после подключения)

3- 206 совершенно правильно, это то, что вы следует ожидать при использовании Range, а это означает Частичный успех контента, и что вы делаете, вы получаете часть контента, если получаете полный контент, который вы получите 200.

поэтому, чтобы подвести итог, ваш код может выглядеть так: Примечание. следуйте за // ***, чтобы увидеть необходимые изменения.

EDIT: все это попало в эту строку

httpURLConnection.setRequestProperty("If-Range", lastModified);

ошибка возникает при установке этого свойства,

В любом случае, когда вы смотрите на это, это бессмысленно, вы спрашиваете, совпадает ли последнее изменение с значением, которое вы только что получили от соединения!, если вы хотите сделать это, вам нужно сохранить lastModified в вашей системе, затем сравните его с тем, который вы получили от URLConn, и сравните его с длиной вашего файла (уже загруженным) затем выполните полную загрузку или возобновите загрузку.

найти новый код ниже:

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());
    }
}

Ответ 2

Посмотрите этот ответ POMATu. Но в любом случае, если вы загружаете файлы по протоколу HTTP, вы можете использовать DownloadManager - системную услугу (начиная с уровня API 9) для длительной загрузки в фоновом режиме. Он обрабатывает соединения HTTP, изменения подключений, перезагрузки и гарантирует, что каждая загрузка будет успешно завершена. И он уже поддерживает возобновление, а также уведомления о ходе выполнения.

Вы можете найти много руководств, таких как this или примеры, например что и многие решения fooobar.com/info/tagged/... .