Downloading a File on Android: From Idea to Working Code
\n\nEvery Android developer sooner or later faces the task of downloading a file from the network. It could be an app update, downloading an image, a PDF document, or a music track. But simply downloading a file is only half the battle. The user must see that the process is ongoing: how much has been downloaded, how much is left, and that the app hasn't frozen.
\n\nIn this article, we will break down a classic question from Stack Overflow that has garnered thousands of views: how to download a file on Android and show progress in a dialog window. We will write the code in Java, using AsyncTask and ProgressDialog (although in modern projects they are often replaced with coroutines or RxJava, understanding the classics is a foundation that hasn't gone anywhere).
Ready? Let's go!
\n\nWhy is it so difficult? Three pitfalls of downloading in Android
\n\nAt first glance, the task is simple: open a connection, read a byte stream, write to a file. But in practice, developers stumble on three things:
\n\n- \n
- The UI thread gets blocked — if you start the download in the main thread, the app will "freeze" and Android will show the "App is not responding" dialog. \n
- Progress doesn't update — even if you count the bytes, you cannot simply change the UI from a background thread. \n
- Configuration changes — the user rotates the screen, and your
Activityis recreated. The dialog disappears, and the download goes nowhere. \n
We will solve all three problems. We'll start with the architecture, then write the code.
\n\nChoosing the tools: AsyncTask and ProgressDialog
\n\nFor educational purposes, we'll use the classic approach:
\n- \n
AsyncTask— for performing background work and publishing progress. \n ProgressDialog— for displaying percentages. \n HttpURLConnection— for the HTTP request (it's still alive, even if deprecated). \n
Important: In real projects today, DownloadManager, WorkManager, or libraries like Retrofit + OkHttp are more commonly used. But understanding how downloading works "by hand" is a must-have for any developer.
Complete code: downloading a file with ProgressDialog
\n\nBelow is a ready-made class for downloading. The code is commented in Russian so you can immediately understand what's happening.
\n\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.os.AsyncTask;\nimport android.os.Environment;\nimport android.widget.Toast;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\n\npublic class DownloadFileTask extends AsyncTask<String, Integer, String> {\n\n private Context context;\n private ProgressDialog progressDialog;\n\n public DownloadFileTask(Context context) {\n this.context = context;\n }\n\n @Override\n protected void onPreExecute() {\n super.onPreExecute();\n // Create and show the progress dialog\n progressDialog = new ProgressDialog(context);\n progressDialog.setTitle("File Download");\n progressDialog.setMessage("Downloading...");\n progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);\n progressDialog.setCancelable(false); // Don't allow accidental closing\n progressDialog.show();\n }\n\n @Override\n protected String doInBackground(String... params) {\n String fileUrl = params[0];\n String fileName = "downloaded_file.pdf"; // Can be passed as a second parameter\n InputStream inputStream = null;\n FileOutputStream outputStream = null;\n\n try {\n // 1. Establish connection\n URL url = new URL(fileUrl);\n HttpURLConnection connec