Android Download Manager Tutorial
Last updated at 21-11-2021
How to download a file from URL in Android
Some common Questions Answered in this Guide are.
- How to use Download Manager in Android using Example?
- How Download Manager and Download Files from URL to Android App?
- How to Download files in Android Local Storage the Right Way?
- How to Download Multiple Files in Android Programmatically using Java
- Download Manager Basics for Android Development
- Download Manager Sample Application in Android
- Download File from URL in App's Internal Storage using Download Manager in Android Programmatically
Introduction to Download Manager in Android
Android has many built-in libraries and services which make it simple for developers to use existing functionalities for various use cases and let developers focus on their Android Application's Core working and features. Downloading a file from a URL and keeping it available on Android's Local Storage is an essential feature that many apps rely on to make useful features in the App. Downloading File from URL in Android is not as simple as making HTTP Request and storing bytes stream in local storage, however, there are challenges that will be needed to tackle like handling the following exception/events:
- Networks Connectivity Breaks
- On Error Detections and Retrying
- Downloading Multiple Files
- Listen to Download Completion Events
- Showing Notification with Progress Bar
- Cancelling Download Requests
- Download Over WiFi or Metered Connection
- Concurrent File Downloads (Simultaneously Download Files)
All these events if we were to handle using our own logic and code it will divert us from our App's Core working, making our app to take more time and effort to manage and release. Android Framework Introduced Download Manager System Service Classes which can be called from your application programmatically assign download job to Download Manager, we can get notified in-app about specific download file tasks requested by our app.
Let's see how we can use the Android Download Manager to Download a File from a URL or Multiple Files.
Sample Application using Download Manager
This application uses Download Manager to request Download
Basic Download Manager Working in Android
Download Manager in Android is a system service that handles process requests by each application in an SQLite DB for managing Download Requests. This means if our app requests some download task using Download Manager, our app will be able to query all the download requests and perform various actions as per the status of download requests.
Now in the above explanation Download Requests and Download Query are the common tasks that our app should be able to do to leverage the rich features of Download Manager in Android. Download Manager comes loaded with 2 nested classes namely DownloadManager.Query and DownloadManager.Request as per the official Download Manager Documentation.
DownlaodManager.Request
can be used to set information about the new Download Request that our applications want to make.
DownloadManager.Query
helps in filtering the status of the app's download requests.
Download Manager is android sends various Broadcast Intents (a way in which Android notifies other apps about certain actions that happen in android) to our app which can be subscribed/detected by our app to take some action.
A common example of Broadcast Intent Action is as follows:
- Detecting the Network Connectivity Changes in App to take relevant action. Most apps show us
No Internet Connected Error
when the device loses network connections. The app actually gets the Broadcast Intent Action that the device connections are lost or regained.
In the same way, Download Manager sends an ACTION_DOWNLOAD_COMPLETE
Broadcast Intent to our app when requested files are downloaded by Download Manager. There are many more Broadcast Intent Action by Download Manager that can be detected which can be seen in this list by Android official documentation on Download Manager.
With the understanding of DownlaodManager.Request
, DownloadManager.Query
, and ACTION_DOWNLOAD_COMPLETE
we can use the functionality of Download Manager to achieve the file downloading URL feature in our app. The following steps will show all the major steps that we need to take to Download a file from a URL using Download Manger.
Step 0: Requirements for Download Manager
Download Manager is available to use from API 9 onwards, meaning that all Android Phones with Android Version 2.3 - 2.3.2 and above will be able to get Download Request from our app and perform the download task.
Step 1a: Declare Permissions in Manifest.xml
File
Download Manager needs a few Permissions to be declared in our app's Manifest.xml
. These permissions are not asked from users but declared in the Android app's Manifest file.
<!-- Internet Access Permission -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<!-- In case you want to Download The File Without Showing Notification -->l̥
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
Step 1b (Optional): Allow Traffic Over HTTP (Only if Files are to be Downloaded from HTTP Source)
Allow HTTP Traffic in Application Attributes in Manifest.xml
File so files which have HTTP are also permitted to be downloaded. By default android:usesCleartextTraffic
is false/disabled in app.
android:usesCleartextTraffic="true"
Step 2: Getting Instance of Download Manager Service
Using getter method named getSystemService
with DOWNLOAD_SERVICE
filter to get DownloadManager object. Following Line will use the Context of our android application and get DownloadManager Instance.
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
Step 3: Download.Request to set infomation about new Download Request
Download.Request object is where information regarding Download is added so DownloadManager can perform as per desired behavior.
DownloadManager.Request newDownloadRequest = new DownloadManager.Request(Uri.parse(downloadUrl))
.setTitle(fileDestination.getName()) // Title
.setDescription("Download Manager Content") // Description of the Download Notification
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) // Visibility of the
.setDestinationUri(Uri.fromFile(fileDestination)) // Uri of the destination file
.setAllowedOverMetered(true) // Set if download is allowed on Mobile network
.setAllowedOverRoaming(true); // Set if download is allowed on roaming network
// enqueue the Download. Request to Download Manager.
downloadTaskId = downloadManager.enqueue(newDownloadRequest);
setTitle
value will be shown in Download Manager Progress Notification in the above case we enter thefileName
as the title shown with a green mark.setDescription
will set the description of download as shown in the image with an orange mark.setNotificationVisibility
is an option to choose if the download is to be shown to the user in the Notification Bar.setDestinationUri
is the Uri where the Download Manager should store the file.Uri.fromFile(fileDestination)
can convert File object to Uri.setAllowedOverMetered()
andsetAllowedOverRoaming()
are available if you want to choose if the file should be downloaded over specific network. Disabling these options is ideal for Large file download requests.
DownloadManager Enqueue New Download Request
downloadTaskId = downloadManager.enqueue(newDownloadRequest);
downloadTaskId
will hold the Download Task Id. This ID is returned by the enqueue function. Download ID can be used by our app to get specific information about Download at anytime using Download. Query Class.
Step 3: Define and Register BroadcastReceiver
// Fetching the download id received with the broadcast
BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// if you want to take some action for specific download id
// you can experiment with this and use this id
// following id is NOT USED in this program and logic
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
// Checking if the received broadcast is for our enqueued download by matching download id
AsyncTask.execute(new Runnable() {
@Override
public void run() {
// following function will run when the download complete intent is recieved
getDownloadInfoAndExtractDownloadedFile();
}
});
}
};
Broadcast Reciever Intent Register to Android using register receiver
function
context.registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
Above Code will register the on download complete
BroadcastReceiver
which will trigger a function to extract a downloaded file and take relevant action.
Download.Query to get Status of ALL Download Requests and Take Relevant Action
DownloadManager.Query query = new DownloadManager.Query();
Cursor c = downloadManager.query(query);
if (c.getCount() != 0) {
while (c.moveToNext()) {
long downloadId = c.getLong(c.getColumnIndexOrThrow(DownloadManager.COLUMN_ID));
String downloadTitle = c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TITLE));
String publicUrl = c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_URI));
String filePath = c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
int reason = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON));
int status = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
Log.i("Download File Info", "-------------Starts--------------");
Log.i("Download File Info", "Public URL: " + publicUrl);
Log.i("Download File Info", "Title/Filename " + downloadTitle);
Log.i("Download File Info", "Local URI " + filePath);
Log.i("Download File Info", "Status " + status);
Log.i("Download File Info", "Reason " + reason);
Log.i("Download File Info", "DownloadID " + downloadId);
Log.i("Download File Info", "**********************************");
if (status == DownloadManager.STATUS_SUCCESSFUL) {
Log.i("Download File Info", "Downloaded + " + downloadTitle + " Status " + status);
// TAKE ACTION WHEN THE FILE WAS FOUND COMPLETELY DOWNLOAED
}else if (status == DownloadManager.STATUS_RUNNING) {
// wait for status to be 8 (successfull)
Log.i("Download Manager", "Downloading a file " + downloadTitle + " Status: " + status);
} else if (status == DownloadManager.STATUS_PENDING) {
Log.i("Download Manager", "PENDING = " + status);
}
}
}
Remove A Download Request by Download ID
In some cases, the user might want to cancel the download request so the DownloadManager
class has a method to remove which takes the download id as argument to cancel or delete the request.
/**
* Removing file from download queue */
private void remove(long downloadId) {
downloadManager.remove(downloadId);
}
Unregistering the DownloadManager BroadcastReceiver
when the app is killed.
@Override
public void onDestroy() {
super.onDestroy();
// Unregister the Download On Complete Listener
unregisterReceiver(downloadManagerHelper.onDownloadComplete);
}
Related post
What is Machine Learning and what is the scope of Machine Learning in ...
Last updated at 19-11-2021