Skip to main content

DownloadManager

There are a lot of way to download files from the Internet in Android. One of them is by using DownloadManager.

Taken from the documentation, DownloadManager is a system service that handles long-running HTTP downloads.

There are a lot of things we can do with DownloadManager:

Prerequisites​

Before using DownloadManager class, we need to add INTERNET permission to our AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<!-- Add this permission: -->
<uses-permission android:name="android.permission.INTERNET" />

<application>
</application>

</manifest>

1. Downloading File​

The first thing we can do is obviously downloading a file. We can achieve this by using the enqueue() method.

Basic Usage​

This example will download a video file from the Internet to the public external storage directory (Downloads folder).

import android.app.DownloadManager
import android.content.Context
import android.net.Uri
import android.os.Environment

// Retrieve DownloadManager instance.
val downloadManager = context.getSystemService(DownloadManager::class.java)

// Call `enqueue` method.
val id = downloadManager?.enqueue(
DownloadManager.Request(
Uri.parse("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
)
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"BigBuckBunny.mp4",
)
)

Downloading to Application's External Files Directory​

We can change the destination folder to application's external files directory by using setDestinationInExternalFilesDir instead:

import android.app.DownloadManager
import android.content.Context
import android.net.Uri

// Retrieve DownloadManager instance.
val downloadManager = context.getSystemService(DownloadManager::class.java)

// Call `enqueue` method.
val id = downloadManager?.enqueue(
DownloadManager.Request(
Uri.parse("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
)
.setDestinationInExternalFilesDir(
context,
"Downloads",
"BigBuckBunny.mp4",
)
)

More Download Options​

We can customize the download condition by customizing the download request:

val downloadManager = context.getSystemService(DownloadManager::class.java)
val id = downloadManager?.enqueue(
DownloadManager.Request(
Uri.parse("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
)
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"BigBuckBunny.mp4",
)
.setTitle("Your Video")
.setDescription("Downloading your awesome video...")
.setRequiresCharging(false)
.setRequiresDeviceIdle(false)
.setAllowedOverRoaming(true)
.setAllowedOverMetered(true)
.setMimeType("video/mp4")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
)

2. Launching Downloads Activity​

We can use ACTION_VIEW_DOWNLOADS intent action to launch an Activity that displays all downloads:

import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat.startActivity

startActivity(
context,
Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).apply {
putExtra(DownloadManager.INTENT_EXTRAS_SORT_BY_SIZE, true)
},
null
)

3. Get Application's Downloads​

It is possible to get all the downloads that our applications made with query() method:

import android.app.DownloadManager
import android.content.Context
import android.util.Log
import androidx.core.database.getIntOrNull
import androidx.core.database.getStringOrNull

val downloadManager = context.getSystemService(DownloadManager::class.java)
downloadManager?.let {
val query = DownloadManager.Query()
val cursor = it.query(query)
while (cursor.moveToNext()) {
val status = cursor.getIntOrNull(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
val title = cursor.getStringOrNull(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE))
Log.i("TAG", "$title: $status")
}
}

In the above example, we are retrieving the status and title of all the downloads that our app made.

Filtering the Downloads​

It is also possible to filter the results by its download ID and/or status:

val downloadManager = context.getSystemService(DownloadManager::class.java)
downloadManager?.let {
val query = DownloadManager.Query()
.setFilterById(100, 101)
.setFilterByStatus(DownloadManager.STATUS_RUNNING or DownloadManager.STATUS_SUCCESSFUL)
val cursor = it.query(query)
while (cursor.moveToNext()) {
val status = cursor.getIntOrNull(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
val title = cursor.getStringOrNull(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE))
Log.i("TAG", "$title: $status")
}
}

4. Removing Download​

It is possible to remove a download from the application with remove() method. Once a download is removed, you can no longer access it through DownloadManager and the downloaded file will be deleted from the storage. If the download is still running, it will be canceled.

import android.app.DownloadManager
import android.content.Context

// val downloadId: Long = ...
val downloadManager = context.getSystemService(DownloadManager::class.java)
downloadManager?.remove(downloadId)

References​