Android Development
File Download
ProgressDialog
Android Tutorials
Mobile App Development

Download a file with Android, and showing the progress in a ProgressDialog

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Downloading files in an Android application is a common requirement for many developers, whether it's downloading content from a website, fetching data from a server, or handling media files. Handling this process efficiently is crucial for maintaining a responsive user interface. In this article, we will focus on downloading a file using Android and displaying the progress using a ProgressDialog.

Android Download Techniques

Android offers several ways to download files:

  1. Using HttpURLConnection: Ideal for straightforward HTTP requests, offering direct control over the request and connection logic.
  2. Using third-party libraries like Retrofit or OkHttp: These libraries simplify network operations with higher-level abstractions.
  3. Download Manager: Managed download operations provided by Android, suitable for larger files.

Here, we'll focus on using HttpURLConnection for downloading a file in the background and updating a ProgressDialog.

Implementing File Download with HttpURLConnection and ProgressDialog

Step 1: Set Up Permissions

First, ensure that you have the necessary permissions in your AndroidManifest.xml:

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

Step 2: Creating the DownloadTask

Create a class that extends AsyncTask to perform the file downloading operation off the main thread. Here's a basic implementation:

java
1public class DownloadTask extends AsyncTask<String, Integer, String> {
2    private Context context;
3    private ProgressDialog progressDialog;
4
5    public DownloadTask(Context context) {
6        this.context = context;
7    }
8
9    @Override
10    protected void onPreExecute() {
11        super.onPreExecute();
12        // Initialize and display progress dialog
13        progressDialog = new ProgressDialog(context);
14        progressDialog.setTitle("Downloading");
15        progressDialog.setMessage("Downloading File...");
16        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
17        progressDialog.setIndeterminate(false);
18        progressDialog.setCancelable(false);
19        progressDialog.show();
20    }
21
22    @Override
23    protected String doInBackground(String... serverUrls) {
24        String filePath = null;
25        HttpURLConnection urlConnection = null;
26        InputStream inputStream = null;
27        FileOutputStream fileOutputStream = null;
28
29        try {
30            URL url = new URL(serverUrls[0]);
31            urlConnection = (HttpURLConnection) url.openConnection();
32            urlConnection.connect();
33
34            // Expect HTTP 200 OK
35            if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
36                return "Server returned HTTP " + urlConnection.getResponseCode()
37                        + " " + urlConnection.getResponseMessage();
38            }
39
40            // Get file length
41            int fileLength = urlConnection.getContentLength();
42
43            // Input stream to read file
44            inputStream = urlConnection.getInputStream();
45            String fileName = "downloadedfile.pdf"; // Change as needed
46            File file = new File(context.getExternalFilesDir(null), fileName);
47            fileOutputStream = new FileOutputStream(file);
48            filePath = file.getAbsolutePath();
49
50            byte[] buffer = new byte[4096];
51            long total = 0;
52            int count;
53            while ((count = inputStream.read(buffer)) != -1) {
54                // Allow cancellation with back button
55                if (isCancelled()) {
56                    inputStream.close();
57                    return null;
58                }
59                total += count;
60                // Publishing the progress....
61                if (fileLength > 0) {
62                    publishProgress((int) (total * 100 / fileLength));
63                }
64                fileOutputStream.write(buffer, 0, count);
65            }
66        } catch (Exception e) {
67            return e.toString();
68        } finally {
69            try {
70                if (fileOutputStream != null) {
71                    fileOutputStream.close();
72                }
73                if (inputStream != null) {
74                    inputStream.close();
75                }
76            } catch (IOException ignored) {}
77
78            if (urlConnection != null) {
79                urlConnection.disconnect();
80            }
81        }
82        return filePath;
83    }
84
85    @Override
86    protected void onProgressUpdate(Integer... progress) {
87        super.onProgressUpdate(progress);
88        // Update progress dialog
89        progressDialog.setProgress(progress[0]);
90    }
91
92    @Override
93    protected void onPostExecute(String result) {
94        super.onPostExecute(result);
95        progressDialog.dismiss();
96        if (result != null) {
97            Toast.makeText(context, "Downloaded to: " + result, Toast.LENGTH_LONG).show();
98        } else {
99            Toast.makeText(context, "Download Error", Toast.LENGTH_LONG).show();
100        }
101    }
102}

Step 3: Execute the DownloadTask

In your activity or fragment, call the DownloadTask with the URL of the file to be downloaded:

java
String fileUrl = "http://example.com/file.pdf";
new DownloadTask(this).execute(fileUrl);

Key Considerations

  • Handling Large Files: Ensure your app can handle large files without running out of memory by using efficient buffering techniques.
  • Network Callback Integration: Consider integrating network callbacks to handle specific network events or errors more robustly.
  • User Interface Responsiveness: Offload any intensive tasks from the UI thread to keep the app responsive.
  • Runtime Permissions (Android 6.0 and above): Implement checks for runtime permissions, especially for external storage access.

Summary

The following table summarizes the key steps and considerations in implementing file download with progress indication in Android:

Step/ConsiderationDescription
PermissionsAdd INTERNET and WRITE_EXTERNAL_STORAGE to AndroidManifest.xml.
Download TaskImplement using AsyncTask or a similar mechanism to handle background processes.
Progress UpdateUse ProgressDialog to give feedback to the user about the download progress.
Error HandlingImplement robust error handling to manage network failures or I/O exceptions gracefully.
File ManagementEnsure proper storage of downloaded files, considering different storage options (internal, external) based on app requirements and Android versions.
UI ResponsivenessDownload files in the background to keep the main UI thread free.

Conclusion

Downloading files in Android while providing user feedback through a ProgressDialog is a fundamental yet powerful technique. With careful implementation and error handling, you can enhance your app's functionality, offering users a seamless experience. Always ensure you’re using the latest Android best practices regarding permissions and background tasks to support a wide range of devices and versions.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions