Downloading a File with Android and Showing Progress in a ProgressDialog

Downloading a File with Android and Showing Progress in a ProgressDialog

6 June 2024 Stephan Petzl Leave a comment Tech-Help

If you’re developing an Android application that requires downloading files, you might want to show the download progress to the user. This guide will walk you through the process of downloading a file and displaying the progress using a ProgressDialog.

Using AsyncTask to Download Files

The AsyncTask class is a great way to perform background operations and update the UI thread simultaneously. Here’s a step-by-step guide on how to achieve this:

Step 1: Import Required Classes

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.PowerManager;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;

Step 2: Initialize the ProgressDialog

// Declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;

// Instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("Downloading...");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);

Step 3: Create an AsyncTask for Downloading the File

private class DownloadTask extends AsyncTask {

    private Context context;
    private PowerManager.WakeLock mWakeLock;

    public DownloadTask(Context context) {
        this.context = context;
    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage();
            }

            int fileLength = connection.getContentLength();

            input = connection.getInputStream();
            output = new FileOutputStream("/sdcard/file_name.extension");

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                if (fileLength > 0)
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
        mWakeLock.acquire();
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        mProgressDialog.dismiss();
        if (result != null)
            Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
    }
}

Step 4: Execute the DownloadTask

// Execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("URL_of_the_file_to_download");

mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        downloadTask.cancel(true); // Cancel the task
    }
});

Permissions

Ensure that you have the necessary permissions in your AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Conclusion

By following the steps outlined above, you can effectively download files in your Android application and display the progress to the user. This approach ensures that the download process is smooth and user-friendly.

Automating Your Mobile App Testing

While developing mobile applications, testing is a crucial part of ensuring quality. Repeato is a no-code test automation tool for iOS and Android that helps you create, run, and maintain automated tests for your apps. Repeato is particularly fast in editing and running tests and works based on computer vision and AI. It allows developers to focus on creating a great product instead of spending time on creating and maintaining tests. Additionally, Repeato enables developers to delegate test automation tasks to non-technical colleagues or QAs. To learn more, visit our homepage.

Like this article? there’s more where that came from!