Download Manager In WebView – Android Studio Tutorial

The download manager is a service that can be used to handle downloads. Set the download URL and when the Download manager is invoked it will download the file in the background. It needs permission to write into storage and permission to access the Internet. There are plenty of features for the download manager. You could take a look at the documentation on Download Manager for Android Developers here. You can implement this on a new project or even on your existing one. I would be implementing Download Manager in WebView for android webview to download file. Let’s start by creating a new Android Studio Project.

Download Source Code – Download Manager Android


Permissions needed

First of all, let’s add all the permissions that we need to Manifest File. Go to the app ->manifest -> AndroidManifest.xml file and all the following permissions.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Seeing these you might have understood for what these permissions are needed. They are for accessing the Internet, Writing into external storage and to access network state.

Now on the XML part, we have to Create a WebView and give it an ID. Go to app -> res -> layout -> activity_main.xml. Then call a WebView and give it an ID, I am giving it the ID web.

XML Part for WebView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/web"/>

</LinearLayout>

That’s all that you have to do in the XML Part. Now we have added XML part of the WebView everything else is done in Java. So go to app -> java -> com.codeseasy.downloadmanager -> MainActivity.java file. Now let’s add the Java part for WebView and also setup Download Manager for our WebView.

Java for Handling Download Manager in WebView

First, we need to ask permission for writing into external storage. This is needed for all the devices running Android Marshmallow and above. Add the codes outside the onCreate method and call the checkDownloadPermission() method inside the onCreate method.

private void checkDownloadPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(MainActivity.this, "Write External Storage permission allows us to save files. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
        }
    }

We have to get the WebView through its ID and load a URL. First, create an object for WebView above the onCreate method. We also require the URL to be loaded on the WebView so add that variable also.

private WebView webView;
private String URL = "https://www.codeseasy.com";

Now inside the onCreate() method, we have to initialize the webView with the ID we have given to our WebView in the XML part. “URL” is a string that contains the website URL which is defined in the previous step.

webView = findViewById(R.id.web);
webView.loadUrl(URL);

Now set JavaScript enabled for the WebView.

webView.getSettings().setJavaScriptEnabled(true);

We have to make sure that the URLs load only inside our WebView. Add these codes to make the URLs to load inside the WebView itself.

webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
});

That’s all on WebView, now we have to set up the download manager in the WebView. For that, we have to set a Download Listener for the WebView.

webView.setDownloadListener(new DownloadListener() {
    @Override
    public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
        //tell what to happen here
    }
});

Inside the Download Listener, we have to create a new request for the Download manager. Add the codes inside Download Listener.

DownloadManager.Request request =new DownloadManager.Request(Uri.parse(url));

We can give a Title and Description for the download.

request.setTitle(URLUtil.guessFileName(url,contentDisposition,mimetype));
request.setDescription("Downloading file...");

If you want a notification on the notification bar saying that “the download is successful” add this line of code.

request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

You can also set the destination directory for the downloads. For that, we just need to specify the directory for the download manager.

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,URLUtil.guessFileName(url, contentDisposition, mimetype));

Now just call the download service which is there in Android and start the download.

DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(request);

You can also make a toast message when the downloading starts.

Toast.makeText(getApplicationContext(),"Downloading...",Toast.LENGTH_SHORT).show();

If you need to show a toast after the download you can use a Broadcast Receiver for it. An error will occur at onComplete, it will be resolved in the next step.

registerReceiver(onComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

You have to close the onDownloadStart and add the following.

BroadcastReceiver onComplete = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(getApplicationContext(),"Downloading Complete",Toast.LENGTH_SHORT).show();
    }
};

That’s all you have set up the download manager for the WebView. I will provide all the codes in MainActivity together so that you could have a look.

Download Source Code – Download Manager Android

package com.codeseasy.downloadmanager;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private String URL = "https://www.codeseasy.com";

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkDownloadPermission();
        webView = findViewById(R.id.web);
        webView.loadUrl(URL);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype));
                request.setDescription("Downloading file...");
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype));
                DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                dm.enqueue(request);
                Toast.makeText(getApplicationContext(), "Downloading...", Toast.LENGTH_SHORT).show();
                registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
            }
            BroadcastReceiver onComplete = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Toast.makeText(getApplicationContext(), "Downloading Complete", Toast.LENGTH_SHORT).show();
                }
            };
        });
    }

    private void checkDownloadPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(MainActivity.this, "Write External Storage permission allows us to save files. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
        }
    }
}

That’s all you have successfully setup download manager in WebView. Now you can download any file directly from your WebView itself.

18 thoughts on “Download Manager In WebView – Android Studio Tutorial”

  1. I implemented this and i was able to download a file,
    however it downloads a .bin file instead of a PDF file which cant open.
    i would appreciate any help on the issue
    thanks.

    Reply
    • Check the download url, and the type. Download manager is something which is within android and the implementation is also correct. So check the download link or it could be an issue with the mobile companies software addon.

      Reply
  2. Good Morning,

    I’m generating the image dynamically, using the downloadable canvas. When it is generated, I add the ‘download’ attribute to a tag. As below:

    function baixarImagemGraduacao(iCodigo) {
    var download = document.getElementById("download");
    var image = document.getElementById("canvas").toDataURL("image/png").replace("image/png", "image/octet-stream");
    var sNomeColaborador = $('#nome_' + iCodigo).text().trim().toLowerCase().replace(/ /g, '_');
    var sNomeGraduacao = $('#graduacao option:selected').text().trim().toLowerCase().replace(/ /g, '_');
    var sNomeArquivo = sNomeColaborador + '_graduacao.png';
    var webview = document.querySelector('#activity_main_webview');
    if (webview) {
    webview.addEventListener('permissionrequest', function(e) {
    if (e.permission === 'download') {
    e.request.allow();
    }
    });
    }
    download.setAttribute("download", sNomeArquivo);
    download.setAttribute("href", image);
    }

    However, when implementing the code made available by you, when trying to call the javascript function downloadImagImagGraduacao, the app simply closes, with no returns.

    I don’t have a lot of knowledge with android, java etc. I’m a full stack developer, focused on the web.

    Reply
  3. Hello, thank you very much for your help, but I would like to consult a problem that I am having with the file, when entering the webview and downloading the pdf it does not have any format, however when I open the file it takes me to the browser and shows me the html page, I try with other urls and the download code works with others but this download method does not work with this url, can you please advise me and tell me what this error may be due to? Thank you very much in advance

    Reply
  4. Hi, i noticed via fiddler, the file download is initiated once after shouldOverrideUrlLoading returns true, but nothing happens after the following line executes:
    dm.enqueue(request);

    End result, i don’t see file downloaded.

    Reply
  5. this project work fine with but i am looking for one thing i couldnt find it in anywhere.
    on my website there is a radio live streaming.
    i need an webview app which can able to pick sound permission and and able to play radio in webview app.
    can you help with this project to solve this issue?

    Reply

Leave a Comment