Подтвердить что ты не робот

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

мой нижеприведенный код для загрузки файла отлично работает, когда не реализует 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

4b9b3361

Ответ 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/... .