Android Downloading File by Showing Progress Bar

When our application does a task that takes a considerable amount of time, it is common sense to show the progress of the task to the user.
This is a good User Experience practice. In this tutorial i will be discussing the implementation of a process-progress dialog.

As an example, i am displaying a progress bar that runs while the app downloads an image from the web. And once the image is downloaded
completely i am showing the image in a image view. You could modify this example and try it with any file type you may wish. That could be fun!

Download Code

Creating new Project

1. Create a new project and fill all the details. File ⇒ New ⇒ Android Project
2. Open your main.xml are create a button to show download progress bar. Also define a ImageView to show downloaded image. Paste the following code in your main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <!-- Download Button -->
    <Button android:id="@+id/btnProgressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Download File with Progress Bar"
        android:layout_marginTop="50dip"/>

    <!-- Image view to show image after downloading -->
    <ImageView android:id="@+id/my_image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

3. Now in your main activity class import necessary classes and buttons. I am starting a new asynctask to download the file after clicking on show progress bar button.

public class AndroidDownloadFileByProgressBarActivity extends Activity {

	// button to show progress dialog
	Button btnShowProgress

	// Progress Dialog
	private ProgressDialog pDialog;

	// Progress dialog type (0 - for Horizontal progress bar)
	public static final int progress_bar_type = 0; 

	// File url to download
	private static String file_url = "http://api.androidhive.info/progressdialog/hive.jpg";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// show progress bar button
		btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
		// Image view to show image after downloading
		my_image = (ImageView) findViewById(R.id.my_image);

		/**
		 * Show Progress bar click event
		 * */
		btnShowProgress.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// starting new Async Task
				new DownloadFileFromURL().execute(file_url);
			}
		});
	}

4. Progress Dialog can be shown using ProgressDialog class. It is a subclass of normal AlertDialog class. So add an alert method in your main activity class.

    /**
	 * Showing Dialog
	 * */
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case progress_bar_type:
			pDialog = new ProgressDialog(this);
			pDialog.setMessage("Downloading file. Please wait...");
			pDialog.setIndeterminate(false);
			pDialog.setMax(100);
			pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			pDialog.setCancelable(true);
			pDialog.show();
			return pDialog;
		default:
			return null;
		}
	}

5. Now we need to add our Async Background thread to download file from url. In your main activity add a asynctask class and name it as DownloadFileFromURL(). After downloading image from the web i am reading the downloaded image from the sdcard and displaying in a imageview.

	/**
	 * Background Async Task to download file
	 * */
	class DownloadFileFromURL extends AsyncTask<String, String, String> {

		/**
		 * Before starting background thread
		 * Show Progress Bar Dialog
		 * */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			showDialog(progress_bar_type);
		}

		/**
		 * Downloading file in background thread
		 * */
		@Override
		protected String doInBackground(String... f_url) {
			int count;
	        try {
	            URL url = new URL(f_url[0]);
	            URLConnection conection = url.openConnection();
	            conection.connect();
	            // getting file length
	            int lenghtOfFile = conection.getContentLength();

	            // input stream to read file - with 8k buffer
	            InputStream input = new BufferedInputStream(url.openStream(), 8192);

	            // Output stream to write file
	            OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");

	            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);
	            }

	            // flushing output
	            output.flush();

	            // closing streams
	            output.close();
	            input.close();

	        } catch (Exception e) {
	        	Log.e("Error: ", e.getMessage());
	        }

	        return null;
		}

		/**
		 * Updating progress bar
		 * */
		protected void onProgressUpdate(String... progress) {
			// setting progress percentage
            pDialog.setProgress(Integer.parseInt(progress[0]));
       }

		/**
		 * After completing background task
		 * Dismiss the progress dialog
		 * **/
		@Override
		protected void onPostExecute(String file_url) {
			// dismiss the dialog after the file was downloaded
			dismissDialog(progress_bar_type);

			// Displaying downloaded image into image view
			// Reading image path from sdcard
			String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
			// setting downloaded into image view
			my_image.setImageDrawable(Drawable.createFromPath(imagePath));
		}

	}

6. Open your AndroidManifest.xml file and add internet connect permission and writing to sdcard permission.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidhive"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AndroidDownloadFileByProgressBarActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <!-- Permission: Allow Connect to Internet -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Permission: Writing to SDCard -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

</manifest>

7. Run your Application and click on show progress bar button to see your progress bar. You can see the downloaded image in imageView once it is downloaded.

android download file and showing progress bar

Final Code

package com.example.androidhive;

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.Dialog;
import android.app.ProgressDialog;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class AndroidDownloadFileByProgressBarActivity extends Activity {

	// button to show progress dialog
	Button btnShowProgress;

	// Progress Dialog
	private ProgressDialog pDialog;
	ImageView my_image;
	// Progress dialog type (0 - for Horizontal progress bar)
	public static final int progress_bar_type = 0; 

	// File url to download
	private static String file_url = "http://api.androidhive.info/progressdialog/hive.jpg";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// show progress bar button
		btnShowProgress = (Button) findViewById(R.id.btnProgressBar);
		// Image view to show image after downloading
		my_image = (ImageView) findViewById(R.id.my_image);
		/**
		 * Show Progress bar click event
		 * */
		btnShowProgress.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// starting new Async Task
				new DownloadFileFromURL().execute(file_url);
			}
		});
	}

	/**
	 * Showing Dialog
	 * */
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case progress_bar_type: // we set this to 0
			pDialog = new ProgressDialog(this);
			pDialog.setMessage("Downloading file. Please wait...");
			pDialog.setIndeterminate(false);
			pDialog.setMax(100);
			pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			pDialog.setCancelable(true);
			pDialog.show();
			return pDialog;
		default:
			return null;
		}
	}

	/**
	 * Background Async Task to download file
	 * */
	class DownloadFileFromURL extends AsyncTask<String, String, String> {

		/**
		 * Before starting background thread
		 * Show Progress Bar Dialog
		 * */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			showDialog(progress_bar_type);
		}

		/**
		 * Downloading file in background thread
		 * */
		@Override
		protected String doInBackground(String... f_url) {
			int count;
	        try {
	            URL url = new URL(f_url[0]);
	            URLConnection conection = url.openConnection();
	            conection.connect();
	            // this will be useful so that you can show a tipical 0-100% progress bar
	            int lenghtOfFile = conection.getContentLength();

	            // download the file
	            InputStream input = new BufferedInputStream(url.openStream(), 8192);

	            // Output stream
	            OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");

	            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);
	            }

	            // flushing output
	            output.flush();

	            // closing streams
	            output.close();
	            input.close();

	        } catch (Exception e) {
	        	Log.e("Error: ", e.getMessage());
	        }

	        return null;
		}

		/**
		 * Updating progress bar
		 * */
		protected void onProgressUpdate(String... progress) {
			// setting progress percentage
            pDialog.setProgress(Integer.parseInt(progress[0]));
       }

		/**
		 * After completing background task
		 * Dismiss the progress dialog
		 * **/
		@Override
		protected void onPostExecute(String file_url) {
			// dismiss the dialog after the file was downloaded
			dismissDialog(progress_bar_type);

			// Displaying downloaded image into image view
			// Reading image path from sdcard
			String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
			// setting downloaded into image view
			my_image.setImageDrawable(Drawable.createFromPath(imagePath));
		}

	}
}
This image is for thumbnail purpose
android download file by showing progress bar