简体   繁体   English

Android WebView:当内容类型为 application/pdf 时下载,如果不是则呈现网页

[英]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.我有一个特定的场景,我在正文中使用唯一的票证发出POST请求以返回结果页面。

The resulting page is either Content-Type : application/pdf or text/html .结果页面是Content-Type : application/pdftext/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).问题是 Android WebView不支持 pdf 的渲染(与 iOS 上的等价物一样)。

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).检查带有主要请求的 http 响应标头,然后使用第二个请求下载文件(如果它是 pdf)并在 PDF 应用程序中打开它(有效)。 But for loading html pages, the second request fails, since the ticket is no longer valid.但是对于加载 html 页面,第二个请求失败,因为票不再有效。

  2. Download both the pdf and the html page and then open in pdf app/WebView locally.下载 pdf 和 html 页面,然后在本地打开 pdf 应用程序/WebView。 This works, both relative links in the web pages is broken.这是有效的,网页中的两个相对链接都已损坏。 Is there a nice way to download them as well?有没有好的方法可以下载它们?

x. 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?是否可以中断 WebView 中的请求以读取响应标头并触发下载(如果它是 pdf),否则继续渲染? Can't find a good answer for this.找不到一个好的答案。

You can use the built in method URLConnection.getContentType() for the exact purpose.您可以将内置方法URLConnection.getContentType()用于确切目的。 Once you get the content type proceed with downloading or pass to the WebView .获得内容类型后,继续下载或传递给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:这是在加载之前拦截 URL 的示例:

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 FetchContentTypeAsync用于后台运行任务

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要下载文件,请检查使用 Android 下载文件,并在 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.设置 WebViewClient 后,它有一些接口来拦截请求,最广泛使用的是shouldOverrideUrlLoading()但你也可以覆盖shouldInterceptRequest()并在那里拦截它。

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Xamarin Android WebView 下载内联pdf内容 - Xamarin Android WebView download inline pdf content 在Android上从浏览器下载具有特定内容类型的文件时,如何打开我的应用程序? - How to open my app when I download a file with specific content-type from the browser, on android? 下载Web内容并在运行时加载Android webview - Download web content and load on Android webview at runtime Android AsyncHttpClient下载包含Content-Type:unkonwn标头的图像文件 - Android AsyncHttpClient download image file with Content-Type: unkonwn header 无法为Android中下载的pdf设置正确的内容类型 - cannot set a correct content-type for downloaded pdf in android 当Content-Type = application / octet-stream时,Android如何处理改造响应? - Android how to handle retrofit response when Content-Type = application/octet-stream? 未指定content-type时,Web服务返回SOAP - Web service returns SOAP when content-type is not specified 下载文件时,Android AsyncHttpClient - “内容类型不允许!” - Android AsyncHttpClient - “Content-Type not allowed!” when downloading files 避免在方向更改时使Webview重新呈现网页[Android] - Avoid webview re-render web page on orientation change [Android] Android Webview 下载管理器下载 PDF 文件 - Android Webview Download manager To Download PDF Files
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM