简体   繁体   中英

Android WebView: Download when content-type is application/pdf and render web page if not

I have a specific scenario where I make a POST request with a unique ticket in the body to get a resulting page back.

The resulting page is either Content-Type : application/pdf or text/html . The ticket is only valid once, so the page can only be loaded once.

Problem is that Android WebView does not support rendering of pdf (as the equivalent on iOS do).

I've tried the following:

  1. Check http response headers with a primary request and then download the file with a second request if it's a pdf and open it in a PDF app (works). But for loading html pages, the second request fails, since the ticket is no longer valid.

  2. Download both the pdf and the html page and then open in pdf app/WebView locally. This works, both relative links in the web pages is broken. Is there a nice way to download them as well?

x. Is it possible to interrupt the request in the WebView to read the response headers and trigger a download if it's a pdf otherwise just continue rendering? Can't find a good answer for this.

You can use the built in method URLConnection.getContentType() for the exact purpose. Once you get the content type proceed with downloading or pass to the WebView .

Imports:

import java.net.URL;
import java.net.URLConnection;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

Here's a sample to intercept the URL before loading:

webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                String requestedUrl = request.getUrl().toString();

                boolean isDownloadableFile = false;

                try {
                    isDownloadableFile = new FetchContentTypeAsync(requestedUrl).execute().get();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // downloadable file / dont load it in webview
                if (isDownloadableFile) {
                    // download the file here
                    return false;
                } else {
                    // non downloadable file / load it in webview
                    view.loadUrl(requestedUrl);
                    return super.shouldOverrideUrlLoading(view, request);
                }
            }
        });

FetchContentTypeAsync is used for running the task in background

private static class FetchContentTypeAsync extends AsyncTask<Void, Void, Boolean> {

        private String requestedUrl;

        FetchContentTypeAsync(String requestedUrl) {
            this.requestedUrl = requestedUrl;
        }

        @Override
        protected Boolean doInBackground(Void... voids) {
            boolean isDownloadableFile = false;
            try {
                URL url = new URL(requestedUrl);
                URLConnection urlConnection = url.openConnection();
                String contentType = urlConnection.getContentType();
                isDownloadableFile = contentType.equalsIgnoreCase("application/pdf");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return isDownloadableFile;
        }
    }

To download a file check Download a file with Android, and showing the progress in a ProgressDialog

After you set the WebViewClient it has some interfaces to intercept the requests the most widely used is shouldOverrideUrlLoading() but you can also override shouldInterceptRequest() and intercept it there.

webView.setWebViewClient(new WebViewClient() {
    @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Check the URL here - if it is a file, 
        // then initiate the download
        return false;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM