Learn all about Android download managers and find the best examples out there! How you can use DownloadManager in android to download any type of file from the Internet? This guide will help you understand what they are, and why they are important and provide tips on how to use them with ease.
An Android download manager helps you manage your downloads on the go, whether it is for videos, music, documents, or other types of files. As you become familiar with this system service, you’ll be able to use these features in your app. In this guide, we’ll explain what android download managers are and provide examples of some of the best ones available.
What is an Android Download Manager?
Download manager is a system service, So that comes from android operating system directly and is also managed by android operating system which makes things very easy. It comes with a lot of inbuilt features such as notification with progress. It also popup a notification when the download is finished. It already handles all download serving directly. So it is very easy solution for us to download any file from Internet.
Create a sample app in android studio
Let’s move to Android Studio and create a new application with EmptyActivity template. In this example, I named the app as DownloadManagerExample. Wait till the sync finished.
Create a Downloader interface
For making this android download manager more accessible, I am creating a Downloader Interface. Just navigate the root directory of project and create new interface named Downloader. and write down the below functions.
package com.androidwave.downloadmanagerexample //return Download id which type is Long. interface Downloader { fun downloadFile(url: String): Long }
It will return Download id which type is Long.
Implement Downloader Interface
Let’s move to the next step just create a new Class that actually implements this downloader Interface like this.
package com.androidwave.downloadmanagerexample import android.app.DownloadManager import android.content.Context import android.os.Environment import androidx.core.net.toUri class AndroidDownloader( private val context: Context ): Downloader { private val downloadManager = context.getSystemService(DownloadManager::class.java) override fun downloadFile(url: String): Long { return -1 } }
Understand how to configure a request
How to configure the download manager request so you’ll be able to take full advantage of their features and make the most out of your android app. see the below point
1. Set the MIME type of our download file
Guys if you have specific use case then you can hardcode the MimeType like for JPEG image it will we image/jpeg for video like video/mp4. Here is a list of common MIME types and helper methods.
// Enter the MimeType type that type file you wish to download setMimeType("*/*")
Let automated MIME type based on URL so let write MIME type parse
The above solution will works fine for while you want to download only one type of file, but what about any type of file. No worry I have a complete solution for that. Let’s write a helper function that parsed any kinds of file. So below function will parse any kinds of file.
private fun parseMimeType(url: String): String { val file = File(url) val map = MimeTypeMap.getSingleton() val ext = MimeTypeMap.getFileExtensionFromUrl(file.name) var type = map.getMimeTypeFromExtension(ext) type = type ?: "*/*" return type; }
Set network types
Which type of network you wish to download this file, such as only WIFI or Mobile Network . Based on need what we can do, can setAllowedNetworkTypes(), Like NETWORK_WIFI or NETWORK_MOBILE Network
Set Notification Visibility
We can also manage notification visibility based on need using this setNotificationVisibility.
- VISIBILITY_VISIBLE_NOTIFY_COMPLETED – the whole duration of the download and also come notification when the download is finished.
- VISIBILITY_VISIBLE – That means It will show progress of download but not when it finished
- VISIBILITY_HIDDEN – Not notification at all
- VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION – This one will notify only completion means user only gets a notification when the download succeeds, but not for the progress
Set Title
While file getting downloading notification you can set title that will display on notification. just like below
setTitle("Title")
Add request header
addRequestHeader() builder function only relevant for the authorised header while you downloading any file that have header protection.
Set destination directory
The last but important you want to set destination directory where you wish to download file. In this example I am setting download directory
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
Finally enqueue the request
downloadManager.enqueue(request)
Finally, AndroidDownloader class looks like this
package com.androidwave.downloadmanagerexample import android.app.DownloadManager import android.content.Context import android.os.Build import android.os.Environment import android.webkit.MimeTypeMap import androidx.core.net.toUri import java.io.File class AndroidDownloader(context: Context) : Downloader { private val downloadManager = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { context.getSystemService(DownloadManager::class.java) } else { context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager } override fun downloadFile(url: String): Long { val fileName= getFileNameFromUri(url); val request = DownloadManager.Request(url.toUri()) .setMimeType(parseMimeType(url)) .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setTitle(fileName) .addRequestHeader("Authorization", "Bearer <token>") .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) return downloadManager.enqueue(request) } private fun parseMimeType(url: String): String { val file = File(url) val map = MimeTypeMap.getSingleton() val ext = MimeTypeMap.getFileExtensionFromUrl(file.name) var type = map.getMimeTypeFromExtension(ext) type = type ?: "*/*" return type; } private fun getFileNameFromUri(url: String): String { return url.substring( url.lastIndexOf('/')+1, url.length); } }
Specify BroadcastReceiver
Specify boradcase revicer So android sytem will send broadcast event to our app to download finished, It will receve callback when download finish. Just create a new class which extends broadcast receiver apply download filter
package com.androidwave.downloadmanagerexample import android.app.DownloadManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent class DownloadCompletedReceiver: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if(intent?.action == "android.intent.action.DOWNLOAD_COMPLETE") { val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L) if(id != -1L) { println("Download with ID $id finished!") } } } }
Register Broadcast Receiver in android manifest
<receiver android:name=".DownloadCompletedReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.DOWNLOAD_COMPLETE" /> </intent-filter> </receiver>
Add internet and WRITE_EXTERNAL_STORAGE permission in android manifest
Open the android manifest file and add below permission. After that you have to manage runtime permission. In this demo I am not implementing runtime permission for that please follow my another artilces Best Practices of Runtime Permissions Android.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Finally let use the DownloadManager
All setup is done let’s use this download manager where you wish to used. In this example I am using it MainActivity. like below
package com.androidwave.downloadmanagerexample import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextView class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val downloader = AndroidDownloader(this) val fileUrl= "https://androidwave.com/wp-content/uploads/2020/01/navigation-component-in-android.png" findViewById<TextView>(R.id.textView).text = fileUrl findViewById<Button>(R.id.button).setOnClickListener { /** Update the URL of file that you wish to download*/ downloader.downloadFile(fileUrl) } } }
Conclusion
All done about the android download manager example app. Here I quickly launch my app, Then you can see how it work, If your file bit large then you can see progress bar also. In my example file is very sort so you did not see progress bar because it download very fast. But ended wit download complete with any type of file.
Only once condition is you should have valid download link. Now navigate you download rectory here is download file which can access afterward.