Android download file with Progressbar okHttp

In android it is often required to download file from server.
I generally use OkHttp and apache common io to download files.

OkHttp : This is the library which I mostly use for my projects.
Apache Common IO : This is the library which I use for file manipulation.

Lets start by adding these library to the build.gradle

    compile group: 'commons-io', name: 'commons-io', version: '2.6'
    compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'

Lets create and util file namely which will be responsible for downloading and showing progress bar.
I just modified the code sample of okHttp for my need


 * Copyright (C) 2015 Square, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * See the License for the specific language governing permissions and
 * limitations under the License.

import android.content.Context;
import android.util.Log;


import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

public final class DownloadUtils {

    String fileName;
    String fileUrl;
    Context mContext;

    File root = android.os.Environment.getExternalStorageDirectory();
    File downloadDir = new File(root.getAbsolutePath() + "/androidfeatures/"); //it is my root directory
    ProgressDialog progress;
    final int totalProgressTime = 100;

     * This method will start downloading the file
    public void startDownload() {;"SKDINFO", "Download started");
        //setup the dirs
        final File tmpFile = new File(downloadDir.getAbsolutePath() + "/" + fileName);
        if (downloadDir.exists() == false) {
  "SKDINFO", "folder created");

        //setup the request
        final Request request = new Request.Builder()

        //setup the progressListner
        final ProgressListener progressListener = new ProgressListener() {
            boolean firstUpdate = true;

            public void update(long bytesRead, long contentLength, boolean done) {
                if (done) {
          "SKDINFO", "Download Complete");

                } else {

                    if (firstUpdate) {
                        firstUpdate = false;
                        if (contentLength == -1) {
                  "SKDINFO", "content-length: unknown");
                        } else {
                  "SKDINFO", "content-length: " + contentLength);

                    if (contentLength != -1) {
              "SKDINFO", "" + (100 * bytesRead) / contentLength);
                        progress.setProgress((int)((100 * bytesRead) / contentLength));

        //init okHttp client
        final OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.MILLISECONDS)
                .addNetworkInterceptor(new Interceptor() {
                    public Response intercept(Chain chain) throws IOException {
                        Response originalResponse = chain.proceed(chain.request());
                        return originalResponse.newBuilder()
                                .body(new ProgressResponseBody(originalResponse.body(), progressListener))

        //send the request and write the file

  "SKDINFO", "Download Starting");

            new Thread(new Runnable() {
                public void run() {
                    try {
                        Response response = client.newCall(request).execute();

                        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                        //download Success now
              "SKDINFO", "Download Completed");
                        FileUtils.copyInputStreamToFile(response.body().byteStream(), tmpFile);
                        response.close(); //close reponse to avoid memory leak
                    }catch (IOException e)




  public DownloadUtils(Context context, String fileUrl, String fileName) {
        this.fileUrl = fileUrl;
        this.fileName = fileName;
        this.mContext = context;
        progress = new ProgressDialog(context);
        progress.setMessage("Downloading form ");
        progress.setCancelable(false);"SKDINFO", "DownloadUtils" + fileName);


     * custom response body
    private static class ProgressResponseBody extends ResponseBody {

        private final ResponseBody responseBody;
        private final ProgressListener progressListener;
        private BufferedSource bufferedSource;

        ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
            this.responseBody = responseBody;
            this.progressListener = progressListener;

        public MediaType contentType() {
            return responseBody.contentType();

        public long contentLength() {
            return responseBody.contentLength();

        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(source(responseBody.source()));
            return bufferedSource;

        private Source source(Source source) {
            return new ForwardingSource(source) {
                long totalBytesRead = 0L;

                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead =, byteCount);
                    // read() returns the number of bytes read, or -1 if this source is exhausted.
                    totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                    progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                    return bytesRead;

     * Listner
    interface ProgressListener {
        void update(long bytesRead, long contentLength, boolean done);


Now Lets use this class.
Create and activity with a button in the layout.

public class DownladActivity extends AppCompatActivity {

    Button downloadbtn;
    Context mContext;

    protected void onCreate(Bundle savedInstanceState) {
        mContext = this;

        downloadbtn = (Button) findViewById(;"SKDINFO", "download activity");

        downloadbtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                Toast.makeText(mContext, "Start", Toast.LENGTH_SHORT).show();
                DownloadUtils down = new DownloadUtils(mContext, "", "");
                // DownloadUtils down = new DownloadUtils(mContext,"","");




  1. Extremely useful information which you have shared here about Android app development. This is a great way to enhance knowledge for us, and also beneficial for us. Thank you for sharing a post like this. Android development agency


Post a Comment