Android download file with Progressbar okHttp

Advertisement


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 DownloadUtils.java which will be responsible for downloading and showing progress bar.
I just modified the code sample of okHttp for my need



   package skd.app.androidfeatures.utils;


/*
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
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() {
        progress.show();
        Log.wtf("SKDINFO", "Download started");
        //setup the dirs
        final File tmpFile = new File(downloadDir.getAbsolutePath() + "/" + fileName);
        if (downloadDir.exists() == false) {
            downloadDir.mkdirs();
            Log.wtf("SKDINFO", "folder created");
        }

        //setup the request
        final Request request = new Request.Builder()
                .url(fileUrl)
                .build();

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

            @Override
            public void update(long bytesRead, long contentLength, boolean done) {
                if (done) {
                    Log.wtf("SKDINFO", "Download Complete");

                } else {

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


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


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

        //send the request and write the file

            Log.wtf("SKDINFO", "Download Starting");

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

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

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

                    }

                }
            }).start();





    }

  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.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progress.setIndeterminate(false);
        progress.setCancelable(false);

      Log.wtf("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;
        }

        @Override
        public MediaType contentType() {
            return responseBody.contentType();
        }

        @Override
        public long contentLength() {
            return responseBody.contentLength();
        }

        @Override
        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;

                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_downlad);
        mContext = this;

        downloadbtn = (Button) findViewById(R.id.button6);

        Log.wtf("SKDINFO", "download activity");


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

                Toast.makeText(mContext, "Start", Toast.LENGTH_SHORT).show();
                DownloadUtils down = new DownloadUtils(mContext, "http://mirrors.jenkins.io/war-stable/latest/jenkins.war", "package.zip");
                // DownloadUtils down = new DownloadUtils(mContext,"http://192.168.0.106/test/package.zip","package.zip");
                down.startDownload();


            }
        });


    }
}








Advertisement

Comments (4)

  1. Your blog is really appreciable. We had also create customized solutions using latest technology at affordable cost to help your start-up grow.
    Hire Mobile App Development Company

    ReplyDelete
  2. Shadow Fight 3 Mod APK is an action and fighting game where players choose a warrior and battle through different challenges. The game has smooth controls, sharp graphics, and a fast combat style that keeps the gameplay exciting. The mod version usually provides extra benefits like unlocked items or faster upgrades, which makes progress easier. Characters have different fighting styles, so players can select moves that match their strategy. Missions, story mode, and battle duels make the game interesting to play again and again. Fans enjoy the animations, weapon choices, and overall fighting experience in this version.

    ReplyDelete
  3. https://skyxchangeid.net/ provides information and guidance for accessing a Sky Exchange account online. The website covers registration, login steps, account features, app access, payment methods, and customer support. Visitors can learn about sports markets, casino options, account security, and responsible gaming practices. It also explains different ID types and common login or account issues, helping users understand the platform and its available services before getting started.

    ReplyDelete
  4. When implementing secure file-transfer mechanisms or managing user authentication workflows inside mobile applications such as configuring network utility tasks with OkHttp and progress tracking seen in this Android download file with Progressbar okHttp guide developers frequently need to handle credential validations and token-based sessions. For platforms operating regional portals, ensuring smooth credential handling is just as crucial as managing backend API calls. Users looking for straightforward navigation to specific utility portals can easily complete an 1.ee login to manage their account preferences and access dedicated digital services securely.

    ReplyDelete