How to download file with Progress bar in Android?

UPDATED: 09 June 2013
Today in this tutorial I'm going to demonstrate the file download example in Android. I've Googled everything about it. There are examples available on the Internet. However you'll find some difficulties when you integrate in your code. So lets see how they implemented...

Source Code (ContextBean.java)
ContextBean used to access application context in any class.
import android.content.Context;
/*
 * This will help you to use application context in any file with in project.
 */
public final class ContextBean {
  private static Context localContext;
  public static Context getLocalContext() {
        return localContext;
  }
  public static void setLocalContext(Context localContext) {
        ContextBean.localContext = localContext;
  }
}

Source Code (MainActivity Class)
//In your main activity file.
protected void onCreate(Bundle savedInstanceState) {
...
ContextBean.setLocalContext(getApplicationContext());
...
}

Source Code (DownloadFile.java)
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.util.Log;

public final class DownloadFile extends AsyncTask {
      // Progress Dialog
      private ProgressDialog pDialog;
       // Progress dialog type (0 - for Horizontal progress bar)
       public static final int progress_bar_type = 0;
       private Activity mainActivity = null;
       private Context mainContext = null;

       public DownloadFile(Activity a,Context c){
        this.mainActivity = a;
        this.mainContext = c;
        pDialog = new ProgressDialog(mainContext);
       }
       protected void onPreExecute() {
        super.onPreExecute();
        pDialog.setMessage("Downloading file. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setMax(100);
        pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        pDialog.setCancelable(false);
        pDialog.show();
       }
       @Override
       protected String doInBackground(String... params) {
              int count;
              try {
               URL url = new URL(params[0]);
               URLConnection conection = url.openConnection();
               conection.connect();
               // this will be useful so that you can show a typical 0-100%
               int lenghtOfFile = conection.getContentLength();
               // download the file
               InputStream input = new BufferedInputStream(url.openStream(),8192);
               /* Output stream
                * Folder path : http://www.javaquery.com/2013/06/how-to-get-data-directory-path-in.html
                */
               String dataDirPath = ContextBean.getLocalContext().getPackageManager().getPackageInfo(
                 ContextBean.getLocalContext().getPackageName(), 0).applicationInfo.dataDir;
               OutputStream output = new FileOutputStream(dataDirPath);
               byte data[] = new byte[1024];
               long total = 0;
               while ((count = input.read(data)) != -1) {
                      total += count;
                      // publishing the progress....
                      // After this onProgressUpdate will be called
                      publishProgress("" + (int) ((total * 100) / lenghtOfFile));
                      // writing data to file
                     output.write(data, 0, count);
               }
               output.flush();
               output.close();
               input.close();
              } catch (Exception e) {
               Log.w("Your_Tag","Download Error", e);
              }
        return null;
       }
       /**
        * Updating progress bar
        * */
       protected void onProgressUpdate(String... progress) {
        // setting progress percentage
        this.pDialog.setProgress(Integer.parseInt(progress[0]));
       }
       /**
        * After completing background task Dismiss the progress dialog
        * **/
       @SuppressWarnings("deprecation")
       @Override
       protected void onPostExecute(String file_url) {
              // dismiss the dialog after the file was downloaded
              pDialog.dismiss();
              AlertDialog alertDialog = new AlertDialog.Builder(mainActivity).create();
              // Setting Dialog Title
              alertDialog.setTitle("Title of Box");
              // Setting Dialog Message
              alertDialog.setMessage("Download Complete");
              // Setting OK Button
              alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
               public void onClick(final DialogInterface dialog,
                 final int which) {
               }
              });
              // Showing Alert Message
              alertDialog.show();
       }
}

Now let see how you can access the class. You can use this class with on click event , Menu item click event, etc... It depends on you how you want to access. I'm accessing this class in Main Activity with
protected void onCreate(Bundle savedInstanceState) {...}
/*
 * You have to pass Activity and Context of the application to class
 * this : Activity (1st)
 * this : Context (2nd)
 */
DownloadFile objDownloadFile = new DownloadDatabase(this, this);
objDownloadFile.execute("http://www.example.com/abc.mp3");
Sometime you may got the exception Cannot execute task : the task has already been executed. Its because if you are dealing with AsyncTask . Its one time use class with one Object/Instance.

Solution
Create new object every time if you want to use DownloadFile.java more than one time.

0 comments :