Android Download file to public storage
To implement the function of “download file” from the internet quickly, we can use DownloadManager. After we have input the appropriate parameter, the system will automatically assign the “download“ to a thread running in background and execute it. That means we do not create a thread and create the DownloadManager in the thread. Notification could be shown during the download.
However, there are limitations with DownloadManager.
The location to save the download file is limited to the public directory: Downloads, Pictures, Movies, etc
Our app cannot have information about the download progress. That means DownloadManger doesn’t report how many bytes out of the total file size have been downloaded until the download is completed and it will broadcast ACTION_DOWNLOAD_COMPLETE. We may need to create a thread to keep on monitoring the thread.
There is no method of DownloadManager to find out the original filename stored on the web. If the download link does not contain the filename, we need to give it a name by ourselves.
Permission
First we add the required permission
Code
The reference code can be found in github here.
We create a button on the layout of MainActivity. We click the button to trigger the download. The below function is added in the OnClickListener of the button.
We can set the download whether can proceed over what kind of network(WiFi, Mobile) and the properties (metered, roaming). We also input the title and description of the Download Notification.
fun startDownloadWithDownloadManager(){ val saveFileName = File(publicDownloadsDirectory, subDirectory + "/" + fileName) val downloadRequest = DownloadManager.Request(Uri.parse(downloadLink)) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE) //set whether Download Notification is visible .setTitle(fileName) // Title of the DownloadNotifications .setDescription("Downloading") // Description of the Download Notification .setRequiresCharging(false) //set if the device is required to be charging to begin download .setAllowedOverMetered(false) //set whether download can proceed over Metered network .setAllowedOverRoaming(false) //set whether download can proceed over Roaming connection .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) //set download can proceed over which network type //.setDestinationUri(Uri.fromFile(saveFileName)) //set the save location of the downloaded file, included filename .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/testFolder/photo.zip") Log.d(TAG, "start download file and save as " + saveFileName.absolutePath) val downloadManager:DownloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager downloadManager.enqueue(downloadRequest) }
And we register below BraodcastReceiver to get notice when the download completes.
val downloadListener = object: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { when (intent?.action) { DownloadManager.ACTION_DOWNLOAD_COMPLETE -> { Log.d(TAG, "ACTION_DOWNLOAD_COMPLETE") } DownloadManager.ACTION_NOTIFICATION_CLICKED -> { Log.d(TAG, "ACTION_NOTIFICATION_CLICKED") } DownloadManager.ACTION_VIEW_DOWNLOADS -> { Log.d(TAG, "ACTION_VIEW_DOWNLOADS") } } ... } }
When we click the button, the Download Notification appears. It automatically disappears when the download completes. And the file is found in the destination folder.
留言
發佈留言