How to download a file and update an Android ProgressDialog
May 21st, 2010 by paolo
I recently made an helper class to download a file from the web and save it to the file sytem while updating a ProgressDialog to let the user know the percentage of the download made. This class has the responsibility to manage the network communication and to send messages to the UI to update the status of the ProgressDialog previously built and displayed.
Before starting to write some code it may be useful to remember to declare in the AndroidManifest.xml the request for the permission to make connections over the Internet and, if we want to save the file on the sd card, the permission to write to the external storage:
-
<uses-permission android:name="android.permission.INTERNET"/>
-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The class I wrote is called DownloadThread, extends th java.lang.Thread and a constructor with four parameters:
- the url of the file to download;
- the path where the downloaded file has to be written;
- the instance of the ProgressDialog to update;
- the handler that will receove the messages to update the UI.
The download process has to be in a separate thread and it has to be started soon after the dialog is displayed. The core of this class is its run method where we first make the connection to the specified url and build the input/output streams to realize the communicaton channel and then we read from the network the file content.
-
public void run() {
-
try {
-
-
/* Open a connection to that URL. */
-
int length = ucon.getContentLength();
-
progressDialog.setMax(length);
-
-
/*
-
* Define InputStreams to read from the URLConnection and
-
* OutputStream to write to file
-
*/
-
-
/*
-
* Read bytes to the Buffer until there is nothing more to read(-1).
-
*/
-
byte[] buffer = new byte[BUFFER_LENGTH];
-
int read;
-
int count = 0;
-
while ((read = bis.read(buffer, 0, BUFFER_LENGTH)) != -1) {
-
fos.write(buffer, 0, read);
-
count += read;
-
Message msg = handler.obtainMessage();
-
Bundle b = new Bundle();
-
b.putInt("count", count);
-
msg.setData(b);
-
handler.sendMessage(msg);
-
}
-
fos.close();
-
Log.d(TAG, "Error: " + e);
-
}
-
}
If we delete lines 9 and 28-32 the code could run in any Java standard environment, the highlighted lines have the resposibility to communicate with the UI and to update it. In particular line 9 sets the upper boung of the progress bar in the ProgressDialog and lines 28-32 update throught the Handler instance the current value of the progress bar.
What we need now is the code of build the ProgressDialog in our Activity e and the related Handler that manage messages from the Thread we have just written.
-
public class MyActvity extends Activity {
-
private static final int DOWNLOAD_DIALOG = 0;
-
....
-
DownloadThread downloadThread;
-
...
-
-
@Override
-
switch(id) {
-
case DOWNLOADDB_DIALOG:
-
final ProgressDialog downloadDialog = new ProgressDialog(MyActvity.this);
-
downloadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-
downloadDialog.setMessage(getText(R.string.home_progress_message));
-
downloadDialog.setCancelable(false);
-
final Handler handler = new Handler() {
-
public void handleMessage(Message msg) {
-
int count = msg.getData().getInt("count");
-
downloadDialog.setProgress(count);
-
if (count>= downloadDialog.getMax()) {
-
dismissDialog(DOWNLOAD_DIALOG);
-
removeDialog(DOWNLOADDB_DIALOG);
-
Toast.makeText(MyActvity.this,
-
getText(R.string.download_ok_message), Toast.LENGTH_SHORT).show();
-
}
-
}
-
};
-
downloadThread = new DownloadThread(url, path
-
handler, downloadDialog);
-
downloadThread.start();
-
return downloadDialog;
-
...
It's all, folks! If you want to see this class in action you can see it in a small free software project called GlutenBuster.
