We have come up with another amazing tutorial on how to download one or more files using Android Download Manager. The download manager was introduced in Android 2.3 (API level 9). One big advantage of Android Download Manager is that it optimizes the handling of long-running downloads in the background. The download manager handles HTTP connections, monitors connectivity changes, reboots, and ensures each download completes successfully. If you want to download large files/streaming, then you can’t use Retrofit or Volley, both recommend using DownloadManager instead, which supports resuming and progress notifications.
In this post, we will cover the following subjects:
- Download Image and Music at the same time using Android Download Manager.
- Display Status of all downloads at any time using a switch.
- Save them to a particular location in external drive.
- Sending notification when download completes.
- Ability to Cancel all downloads.
We will download Image and Music from the following URL:
Image URL | http://androidtutorialpoint.comli.com/DownloadManager/Beauty.jpg |
Music URL | http://androidtutorialpoint.comli.com/DownloadManager/AndroidDownloadManager.mp3 |
Pre-requisites
- Android Studio installed on your PC (Unix or Windows).
- A real time android device (Smartphone or Tablet) configured with Android Studio.
- A basic knowledge of Android lifecycle and different classes & functions used in Android Studio.
Creating a New Project
Add Permissions
Add the following permission to your AndroidManifest.xml file:
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Now, we will describe each topic in detail through each function which can be implemented through Android Download Manager. We have made separate functions for download data, show status, complete download notification and cancel downloads.
Generate URI
First, we will have to generate URI from URL. So here, we will generate two URI each for Image and Music URL.
Uri image_uri = Uri.parse("http://androidtutorialpoint.comli.com/DownloadManager/Beauty.jpg");
Uri music_uri = Uri.parse
("http://androidtutorialpoint.comli.com/DownloadManager/AndroidDownloadManager.mp3");
Download Data from URL using Android Download Manager
DownloadData()
function will be used to download data from the internet.
DownloadData
private long DownloadData (Uri uri, View v) {
long downloadReference;
downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("Data Download");
request.setDescription("Android Data download using DownloadManager.");
if(v.getId() == R.id.DownloadMusic)
request.setDestinationInExternalFilesDir(MainActivity.this,
Environment.DIRECTORY_DOWNLOADS,"AndroidTutorialPoint.mp3");
else if(v.getId() == R.id.DownloadImage)
request.setDestinationInExternalFilesDir(MainActivity.this,
Environment.DIRECTORY_DOWNLOADS,"AndroidTutorialPoint.jpg");
downloadReference = downloadManager.enqueue(request);
Button DownloadStatus = (Button) findViewById(R.id.DownloadStatus);
DownloadStatus.setEnabled(true);
Button CancelDownload = (Button) findViewById(R.id.CancelDownload);
CancelDownload.setEnabled(true);
return downloadReference;
}
Description of the above code:
downloadReference
: It is a unique id that we will refer for specific download request. request
: Instance of DownloadManager will be created through getSystemService
by passing DOWNLOAD_SERVICE
. A new request is generated in the next statement using DownloadManager.Request(uri)
. setDestinationInExternalFilesDir
: This will be used to save file in external downloads folder. downloadManager.enqueue(request)
: Enqueue a new download corresponding to request. The download will start automatically once the download manager is ready to execute it and connectivity is available.
Check Download Status
Check_Image_Status()
function will be used to get the status of the Image Download. Refer to the following code:
Check_Image_Status
private void Check_Image_Status(long Image_DownloadId) {
DownloadManager.Query ImageDownloadQuery = new DownloadManager.Query();
ImageDownloadQuery.setFilterById(Image_DownloadId);
Cursor cursor = downloadManager.query(ImageDownloadQuery);
if(cursor.moveToFirst()){
DownloadStatus(cursor, Image_DownloadId);
}
}
Description of above code:
DownloadManager.Query()
: This is used to filter Android download manager queries. Here, we are providing Image_DownloadId
in setFilterById()
to include only downloads with given Id. downloadManager.query(ImageDownloadQuery)
: This is used to Query the Android download manager about downloads that have been requested. - Cursor: A Cursor over the result set of downloads, with columns consisting of all the
COLUMN_*
constants. Now this cursor will be used to get the status of download in DownloadStatus()
function.
DownloadStatus
private void DownloadStatus(Cursor cursor, long DownloadId){
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
int filenameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
String filename = cursor.getString(filenameIndex);
String statusText = "";
String reasonText = "";
switch(status){
case DownloadManager.STATUS_FAILED:
statusText = "STATUS_FAILED";
switch(reason){
case DownloadManager.ERROR_CANNOT_RESUME:
reasonText = "ERROR_CANNOT_RESUME";
break;
case DownloadManager.ERROR_DEVICE_NOT_FOUND:
reasonText = "ERROR_DEVICE_NOT_FOUND";
break;
case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
reasonText = "ERROR_FILE_ALREADY_EXISTS";
break;
case DownloadManager.ERROR_FILE_ERROR:
reasonText = "ERROR_FILE_ERROR";
break;
case DownloadManager.ERROR_HTTP_DATA_ERROR:
reasonText = "ERROR_HTTP_DATA_ERROR";
break;
case DownloadManager.ERROR_INSUFFICIENT_SPACE:
reasonText = "ERROR_INSUFFICIENT_SPACE";
break;
case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
reasonText = "ERROR_TOO_MANY_REDIRECTS";
break;
case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
reasonText = "ERROR_UNHANDLED_HTTP_CODE";
break;
case DownloadManager.ERROR_UNKNOWN:
reasonText = "ERROR_UNKNOWN";
break;
}
break;
case DownloadManager.STATUS_PAUSED:
statusText = "STATUS_PAUSED";
switch(reason){
case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
reasonText = "PAUSED_QUEUED_FOR_WIFI";
break;
case DownloadManager.PAUSED_UNKNOWN:
reasonText = "PAUSED_UNKNOWN";
break;
case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
reasonText = "PAUSED_WAITING_FOR_NETWORK";
break;
case DownloadManager.PAUSED_WAITING_TO_RETRY:
reasonText = "PAUSED_WAITING_TO_RETRY";
break;
}
break;
case DownloadManager.STATUS_PENDING:
statusText = "STATUS_PENDING";
break;
case DownloadManager.STATUS_RUNNING:
statusText = "STATUS_RUNNING";
break;
case DownloadManager.STATUS_SUCCESSFUL:
statusText = "STATUS_SUCCESSFUL";
reasonText = "Filename:\n" + filename;
break;
}
if(DownloadId == Music_DownloadId) {
Toast toast = Toast.makeText(MainActivity.this,
"Music Download Status:" + "\n" + statusText + "\n" +
reasonText,
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
else {
Toast toast = Toast.makeText(MainActivity.this,
"Image Download Status:"+ "\n" + statusText + "\n" +
reasonText,
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
}
}, 3000);
}
}
The above code is pretty much self explanatory. We are simply printing status according to the value of COLUMN_REASON
returned by Android Download Manager.
Similarly, we have made function for checking status of Music file, i.e., Check_Music_Status()
.
Cancel all Downloads
To cancel a download, we will simply use:
downloadManager.remove(Image_DownloadId);
downloadManager.remove(Music_DownloadId);
The Broadcast Receivers
The last part of our tutorial is broadcast receiver. Android DownloadManager sends ACTION_DOWNLOAD_COMPLETE
broadcast intent when a download completes. So we will set filter when download completes and registers receiver:
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(downloadReceiver, filter);
private BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if(referenceId == Image_DownloadId) {
Toast toast = Toast.makeText(MainActivity.this,
"Image Download Complete", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
else if(referenceId == Music_DownloadId) {
Toast toast = Toast.makeText(MainActivity.this,
"Music Download Complete", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
}
};
So in the above code, broadcast Intent is received, its referenceId
is compared and accordingly Toast message is displayed.
So finally, we have covered all aspects of Android Download Manager. Still, if you have any doubts or suggestions, please comment or mail us.