In this tutorial we are going to learn how to download pdf, doc , video, mp3, zip ,etc. files from server and save them in device memory.
Below are certain things that we are going to learn in this tutorial :
1. Download Files – Download Files from Server Url.
2. Save Files – Create Folder in device and save the dowloaded files.
3. Download Multiple Files – Download Many Files at a time.
1. Create a new project in Android Studio by navigating to File ⇒ New Android ⇒ Application Project and fill required details. By default my activity is MainActivity.java.
2. Open res=>values=strings.xml and add the following strings to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<resources> <string name="app_name">Android Download Demo</string> <string name="download_Pdf">Download pdf</string> <string name="download_Doc">Download Doc</string> <string name="download_zip">Download Zip</string> <string name="download_video">Download Video</string> <string name="download_mp3">Download MP3</string> <string name="openFolder">Open Downloaded Folder</string> <string name="downloadStarted">Download Started…</string> <string name="downloadCompleted">Download Completed…</string> <string name="downloadFailed">Download Failed…</string> <string name="downloadAgain">Download Again</string> </resources> |
3. Create a xml layout naming activity_main.xml and add the following code. In this layout there are some Buttons for showing downloading different type of files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#eeeeee" android:orientation="vertical" android:padding="5dp"> <!-- Download Pdf Layout --> <Button android:id="@+id/downloadPdf" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/download_Pdf" /> <!-- Download Doc Layout --> <Button android:id="@+id/downloadDoc" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/download_Doc" /> <!-- Download Zip File Layout --> <Button android:id="@+id/downloadZip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/download_zip" /> <!-- Download Video File Layout --> <Button android:id="@+id/downloadVideo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/download_video" /> <!-- Download MP3 File Layout --> <Button android:id="@+id/downloadMp3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/download_mp3" /> <!-- Open Downloaded Folder --> <Button android:id="@+id/openDownloadedFolder" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="@string/openFolder" /> </LinearLayout> |
4. Create a Utils.java class and write all download urls here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.androiddownloaddemo; /** * Created by SONU on 29/10/15. */ public class Utils { //String Values to be Used in App public static final String downloadDirectory = "Androhub Downloads"; public static final String mainUrl = "https://androhub.com/demo/"; public static final String downloadPdfUrl = "https://androhub.com/demo/demo.pdf"; public static final String downloadDocUrl = "https://androhub.com/demo/demo.doc"; public static final String downloadZipUrl = "https://androhub.com/demo/demo.zip"; public static final String downloadVideoUrl = "https://androhub.com/demo/demo.mp4"; public static final String downloadMp3Url = "https://androhub.com/demo/demo.mp3"; } |
5. Create a CheckForSDCard.java class for checking if SDCard is present or not.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.androiddownloaddemo; import android.os.Environment; public class CheckForSDCard { //Check If SD Card is present or not method public boolean isSDCardPresent() { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { return true; } return false; } } |
6. Now create a DownloadTask.java and add the following code. In this code AsyncTask is used for downloading data from server. There are several main steps in doInBackground(Void…arg0) that are listed below :
1. Converting download url into URL:
1 |
URL url = new URL(downloadUrl); |
2. Opening Url Connection for data downloading:
1 |
HttpURLConnection c = (HttpURLConnection) url.openConnection(); |
3. Setting request method to server:
1 |
c.setRequestMethod("GET"); |
4. Connect the open connection:
1 |
c.connect(); |
5. Create a directory in SD Card if not present:
1 2 3 |
File apkStorage = new File( Environment.getExternalStorageDirectory() + "/" + Utils.downloadDirectory); |
1 2 3 4 |
if (!apkStorage.exists()) { apkStorage.mkdir(); Log.e(TAG, "Directory Created."); } |
6. Create an Output file i.e. download file inside above created directory:
1 |
String downloadFileName = downloadUrl.replace(Utils.mainUrl, "");//Create file name by picking download file name from URL |
1 |
File outputFile = new File(apkStorage, downloadFileName); |
1 2 3 4 |
if (!outputFile.exists()) { outputFile.createNewFile(); Log.e(TAG, "File Created"); } |
Note: Give extension to your outputFile like .pdf, .mp3, .mp4 etc.
7. Download File and write it over the outputFile created:
1 2 3 4 5 6 7 8 9 |
FileOutputStream fos = new FileOutputStream(outputFile);//Get OutputStream for NewFile Location InputStream is = c.getInputStream();//Get InputStream for connection byte[] buffer = new byte[1024];//Set buffer type int len1 = 0;//init length while ((len1 = is.read(buffer)) != -1) { fos.write(buffer, 0, len1);//Write new file } |
8. Close all connection after downloading:
1 2 |
fos.close(); is.close(); |
Full Code of DownloadTask.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
package com.androiddownloaddemo; import android.content.Context; import android.os.AsyncTask; import android.os.Environment; import android.os.Handler; import android.util.Log; import android.widget.Button; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * Created by SONU on 29/10/15. */ public class DownloadTask { private static final String TAG = "Download Task"; private Context context; private Button buttonText; private String downloadUrl = "", downloadFileName = ""; public DownloadTask(Context context, Button buttonText, String downloadUrl) { this.context = context; this.buttonText = buttonText; this.downloadUrl = downloadUrl; downloadFileName = downloadUrl.replace(Utils.mainUrl, "");//Create file name by picking download file name from URL Log.e(TAG, downloadFileName); //Start Downloading Task new DownloadingTask().execute(); } private class DownloadingTask extends AsyncTask<Void, Void, Void> { File apkStorage = null; File outputFile = null; @Override protected void onPreExecute() { super.onPreExecute(); buttonText.setEnabled(false); buttonText.setText(R.string.downloadStarted);//Set Button Text when download started } @Override protected void onPostExecute(Void result) { try { if (outputFile != null) { buttonText.setEnabled(true); buttonText.setText(R.string.downloadCompleted);//If Download completed then change button text } else { buttonText.setText(R.string.downloadFailed);//If download failed change button text new Handler().postDelayed(new Runnable() { @Override public void run() { buttonText.setEnabled(true); buttonText.setText(R.string.downloadAgain);//Change button text again after 3sec } }, 3000); Log.e(TAG, "Download Failed"); } } catch (Exception e) { e.printStackTrace(); //Change button text if exception occurs buttonText.setText(R.string.downloadFailed); new Handler().postDelayed(new Runnable() { @Override public void run() { buttonText.setEnabled(true); buttonText.setText(R.string.downloadAgain); } }, 3000); Log.e(TAG, "Download Failed with Exception - " + e.getLocalizedMessage()); } super.onPostExecute(result); } @Override protected Void doInBackground(Void... arg0) { try { URL url = new URL(downloadUrl);//Create Download URl HttpURLConnection c = (HttpURLConnection) url.openConnection();//Open Url Connection c.setRequestMethod("GET");//Set Request Method to "GET" since we are grtting data c.connect();//connect the URL Connection //If Connection response is not OK then show Logs if (c.getResponseCode() != HttpURLConnection.HTTP_OK) { Log.e(TAG, "Server returned HTTP " + c.getResponseCode() + " " + c.getResponseMessage()); } //Get File if SD card is present if (new CheckForSDCard().isSDCardPresent()) { apkStorage = new File( Environment.getExternalStorageDirectory() + "/" + Utils.downloadDirectory); } else Toast.makeText(context, "Oops!! There is no SD Card.", Toast.LENGTH_SHORT).show(); //If File is not present create directory if (!apkStorage.exists()) { apkStorage.mkdir(); Log.e(TAG, "Directory Created."); } outputFile = new File(apkStorage, downloadFileName);//Create Output file in Main File //Create New File if not present if (!outputFile.exists()) { outputFile.createNewFile(); Log.e(TAG, "File Created"); } FileOutputStream fos = new FileOutputStream(outputFile);//Get OutputStream for NewFile Location InputStream is = c.getInputStream();//Get InputStream for connection byte[] buffer = new byte[1024];//Set buffer type int len1 = 0;//init length while ((len1 = is.read(buffer)) != -1) { fos.write(buffer, 0, len1);//Write new file } //Close all connection after doing task fos.close(); is.close(); } catch (Exception e) { //Read exception if something went wrong e.printStackTrace(); outputFile = null; Log.e(TAG, "Download Error Exception " + e.getMessage()); } return null; } } } |
7. Now create MainActivity.java and add the following code. In this code i am starting AsyncTask on button click.
But before downloading it is necessary there should be a proper internet connection. So for this I had created a method naming isInternetConnected() that will return true or false.
If you are new in how to detect internet connection then check Detect Internet Connection Tutorial.
Last Button is for Opening downloaded folder and the code for opening download folder is below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//Open downloaded folder private void openDownloadedFolder() { //First check if SD Card is present or not if (new CheckForSDCard().isSDCardPresent()) { //Get Download Directory File File apkStorage = new File( Environment.getExternalStorageDirectory() + "/" + Utils.downloadDirectory); //If file is not present then display Toast if (!apkStorage.exists()) Toast.makeText(MainActivity.this, "Right now there is no directory. Please download some file first.", Toast.LENGTH_SHORT).show(); else { //If directory is present Open Folder /** Note: Directory will open only if there is a app to open directory like File Manager, etc. **/ Intent intent = new Intent(Intent.ACTION_GET_CONTENT); Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/" + Utils.downloadDirectory); intent.setDataAndType(uri, "file/*"); startActivity(Intent.createChooser(intent, "Open Download Folder")); } } else Toast.makeText(MainActivity.this, "Oops!! There is no SD Card.", Toast.LENGTH_SHORT).show(); } |
Full MainActivity.java Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
package com.androiddownloaddemo; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.io.File; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static Button downloadPdf, downloadDoc, downloadZip, downloadVideo, downloadMp3, openDownloadedFolder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); setListeners(); } //Initialize al Views private void initViews() { downloadPdf = (Button) findViewById(R.id.downloadPdf); downloadDoc = (Button) findViewById(R.id.downloadDoc); downloadZip = (Button) findViewById(R.id.downloadZip); downloadVideo = (Button) findViewById(R.id.downloadVideo); downloadMp3 = (Button) findViewById(R.id.downloadMp3); openDownloadedFolder = (Button) findViewById(R.id.openDownloadedFolder); } //Set Listeners to Buttons private void setListeners() { downloadPdf.setOnClickListener(this); downloadDoc.setOnClickListener(this); downloadZip.setOnClickListener(this); downloadVideo.setOnClickListener(this); downloadMp3.setOnClickListener(this); openDownloadedFolder.setOnClickListener(this); } @Override public void onClick(View view) { //Before starting any download check internet connection availability switch (view.getId()) { case R.id.downloadPdf: if (isConnectingToInternet()) new DownloadTask(MainActivity.this, downloadPdf, Utils.downloadPdfUrl); else Toast.makeText(MainActivity.this, "Oops!! There is no internet connection. Please enable internet connection and try again.", Toast.LENGTH_SHORT).show(); break; case R.id.downloadDoc: if (isConnectingToInternet()) new DownloadTask(MainActivity.this, downloadDoc, Utils.downloadDocUrl); else Toast.makeText(MainActivity.this, "Oops!! There is no internet connection. Please enable internet connection and try again.", Toast.LENGTH_SHORT).show(); break; case R.id.downloadZip: if (isConnectingToInternet()) new DownloadTask(MainActivity.this, downloadZip, Utils.downloadZipUrl); else Toast.makeText(MainActivity.this, "Oops!! There is no internet connection. Please enable internet connection and try again.", Toast.LENGTH_SHORT).show(); break; case R.id.downloadVideo: if (isConnectingToInternet()) new DownloadTask(MainActivity.this, downloadVideo, Utils.downloadVideoUrl); else Toast.makeText(MainActivity.this, "Oops!! There is no internet connection. Please enable internet connection and try again.", Toast.LENGTH_SHORT).show(); break; case R.id.downloadMp3: if (isConnectingToInternet()) new DownloadTask(MainActivity.this, downloadMp3, Utils.downloadMp3Url); else Toast.makeText(MainActivity.this, "Oops!! There is no internet connection. Please enable internet connection and try again.", Toast.LENGTH_SHORT).show(); break; case R.id.openDownloadedFolder: openDownloadedFolder(); break; } } //Open downloaded folder private void openDownloadedFolder() { //First check if SD Card is present or not if (new CheckForSDCard().isSDCardPresent()) { //Get Download Directory File File apkStorage = new File( Environment.getExternalStorageDirectory() + "/" + Utils.downloadDirectory); //If file is not present then display Toast if (!apkStorage.exists()) Toast.makeText(MainActivity.this, "Right now there is no directory. Please download some file first.", Toast.LENGTH_SHORT).show(); else { //If directory is present Open Folder /** Note: Directory will open only if there is a app to open directory like File Manager, etc. **/ Intent intent = new Intent(Intent.ACTION_GET_CONTENT); Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/" + Utils.downloadDirectory); intent.setDataAndType(uri, "file/*"); startActivity(Intent.createChooser(intent, "Open Download Folder")); } } else Toast.makeText(MainActivity.this, "Oops!! There is no SD Card.", Toast.LENGTH_SHORT).show(); } //Check if internet is present or not private boolean isConnectingToInternet() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager .getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) return true; else return false; } } |
8. Finally come to AndroidManifest.xml file and add below several permissions to Manifest file.
1 2 3 4 5 6 7 8 9 |
<!-- Permission required for Downloading Files --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Permission required for Checking Internet Connection --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Permission required for Reading Writing SD Card/Memory --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
9. Finally, all done you can use above steps for downloading any kind of files.
Thanks.
Subscribe to us and get the latest news.
95 Comments
Dharmesh Patel
Tuesday, June 30th, 2020Not working in Android 10(Q) api 29.
Dharmesh Patel
Tuesday, June 30th, 2020File can’t download in Android 10(Q) API 29.
Dr. Droid
Wednesday, July 1st, 2020Hi Dharmesh,
The code is written for old devices I think you have to provide runtime permission (https://www.androhub.com/working-android-marshmallow-6-0-permissions/). Let me know if the issue is not related to permissions.
Thanks