25

Is there any way to get downloading file progress when using square`s OkHttp?

I did not find any solution in Recipes.

They have class Call which can get content asynchronically, but there is no method to get current progress.

Kalyaganov Alexey
  • 1,701
  • 1
  • 16
  • 23

3 Answers3

30

Oops answer was obvious. Sorry for dumb question. Just need to read InputStream as usual.

private class AsyncDownloader extends AsyncTask<Void, Long, Boolean> {
    private final String URL = "file_url";

    @Override
    protected Boolean doInBackground(Void... params) {
        OkHttpClient httpClient = new OkHttpClient();
        Call call = httpClient.newCall(new Request.Builder().url(URL).get().build());
        try {
            Response response = call.execute();
            if (response.code() == 200) {
                InputStream inputStream = null;
                try {
                    inputStream = response.body().byteStream();
                    byte[] buff = new byte[1024 * 4];
                    long downloaded = 0;
                    long target = response.body().contentLength();

                    publishProgress(0L, target);
                    while (true) {
                        int readed = inputStream.read(buff);
                        if(readed == -1){
                            break;
                        }
                        //write buff
                        downloaded += readed;
                        publishProgress(downloaded, target);
                        if (isCancelled()) {
                            return false;
                        }
                    }
                    return downloaded == target;
                } catch (IOException ignore) {
                    return false;
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                }
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    protected void onProgressUpdate(Long... values) {
        progressBar.setMax(values[1].intValue());
        progressBar.setProgress(values[0].intValue());

        textViewProgress.setText(String.format("%d / %d", values[0], values[1]));
    }

    @Override
    protected void onPostExecute(Boolean result) {
        textViewStatus.setText(result ? "Downloaded" : "Failed");
    }
}
Kalyaganov Alexey
  • 1,701
  • 1
  • 16
  • 23
  • 7
    Isn't there a more elegant way to do this? Like okHttpClient.newCall(request).notifyProgress(callback)... or something like that... – josketres Jan 08 '15 at 16:26
  • Great answer but one more question... I see that we have a inputstream... To pass that to a file do we have to loop through the entire stream again and convert it to a file? Can you show how you can actually get the File object that has been downloaded? – Marcus Gabilheri Apr 01 '15 at 18:48
  • @MarcusGabilheri are you talking about that? http://stackoverflow.com/a/10857407/1979290 – Kalyaganov Alexey Apr 02 '15 at 11:01
  • @Kalyaganov Alexey yes. I figured out yesterday. Sorry was a stupid question :(. My problem is that I was trying to use the input stream after I was do e loading the file. – Marcus Gabilheri Apr 02 '15 at 12:37
  • every time in the while loop ,you publish the progress.So it's like being blocked – Francis Shi Nov 02 '15 at 10:11
  • @FrancisShi yes, but you can extend this solution and add bytes threshold to publish. – Kalyaganov Alexey Nov 03 '15 at 10:38
  • @KalyaganovAlexey i am trying to download pdf file but response.body().contentLength() always returns -1 – H Raval Jul 12 '16 at 07:27
  • @HRaval this means that content length is not specified in response. This can happen, blame the back end. – Semyon Danilov Dec 09 '16 at 15:19
  • 18
    This answer, generally, is wrong, because it shows the progress of copying bytes from response input stream, which is available only when file is FULLY downloaded. So if you have a 10 megabyte file and network speed 1MB/s, you will see 0% for 10 secs and then very fast progress from 0% to 100%. – Semyon Danilov Dec 09 '16 at 15:21
  • @SemyonDanilov ++ – Vlad Feb 16 '20 at 18:21
9

You can use the okHttp receipe : Progress.java

Christian
  • 748
  • 7
  • 23
-1

every time in the while loop ,you publish the progress.So it's like being blocked

Francis Shi
  • 395
  • 4
  • 8