You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中WebView点击PDF链接无法获取URL的解决方法

解决WebView中PDF链接无法获取及打开的问题

我帮你排查了代码里的几个关键问题,这应该能解决你遇到的PDF链接无法获取、无法正常打开的情况:

问题根源

  1. 过时的URL拦截方法:你用的shouldOverrideUrlLoading(WebView view, String url)已经被废弃,Android 7.0+的WebView会优先调用带WebResourceRequest参数的重载方法,导致PDF链接可能没被拦截到。
  2. PDF链接判断逻辑错误:URLUtil.isFileUrl(url)只识别file://开头的本地文件链接,但大多数网站的PDF是http/https的远程链接,所以这个判断不会触发Google Docs预览逻辑。
  3. DownloadListener的冲突:当WebView识别到可下载的资源(比如PDF)时,会直接触发DownloadListener,而不会走shouldOverrideUrlLoading,导致你在后者里拿不到PDF的URL。

解决方案步骤

1. 替换为新版URL拦截方法

使用shouldOverrideUrlLoading(WebView view, WebResourceRequest request)来拦截所有链接,包括PDF,同时兼容旧版本。

2. 正确识别PDF链接

通过URL后缀(.pdf)来判断是否是PDF链接,覆盖远程PDF的场景。

3. 统一处理URL获取逻辑

在shouldOverrideUrlLoading和DownloadListener里都加入URL日志记录,确保能捕获到PDF的URL;如果需要在WebView内预览PDF,就拦截下载请求,改用Google Docs加载。

4. 优化WebSettings配置

开启必要的设置,比如允许访问文件、启用DOM存储,确保Google Docs预览功能正常。

修改后的完整代码

public class WebViewActivity extends AppCompatActivity {
    WebView webView;
    TextView title;
    ActivityWebViewBinding binding;
    String data;
    Dialog dialog;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityWebViewBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        webView = binding.webView;
        title = binding.title;

        binding.backIcon.setOnClickListener(v -> onBackPressed());
        data = getIntent().getStringExtra("url");

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setDisplayZoomControls(false);
        webSettings.setLoadsImagesAutomatically(true); // 修正之前的赋值错误
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setSupportMultipleWindows(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setSupportZoom(true);
        webSettings.setAllowFileAccess(true); // 允许文件访问,确保PDF预览正常
        webSettings.setDomStorageEnabled(true); // 启用DOM存储,兼容Google Docs

        webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        webView.setScrollbarFadingEnabled(false);

        // 处理下载请求,同时捕获PDF URL
        webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
            Log.d("PDF_URL", "从DownloadListener捕获到PDF链接: " + url);
            // 如果要在WebView内预览,就拦截下载,用Google Docs打开
            if (mimetype.equals("application/pdf") || url.endsWith(".pdf")) {
                String googleDocsUrl = "https://docs.google.com/viewer?url=" + url;
                webView.loadUrl(googleDocsUrl);
            } else {
                // 其他文件正常下载
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                request.allowScanningByMediaScanner();
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "myPDFile.pdf");
                DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                dm.enqueue(request);
            }
        });

        dialog = CommonMethod.getDialog(this);
        dialog.show();

        webView.setWebViewClient(new WebViewClient() {
            // 新版URL拦截方法(Android 7.0+)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                String url = request.getUrl().toString();
                Log.d("TAG", "处理链接点击: " + url);
                handlePdfUrl(view, url);
                return true;
            }

            // 兼容旧版本的URL拦截方法
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.d("TAG", "处理旧版链接点击: " + url);
                handlePdfUrl(view, url);
                return true;
            }

            // 统一处理PDF链接的方法
            private void handlePdfUrl(WebView view, String url) {
                String googleDocs = "https://docs.google.com/viewer?url=";
                // 通过后缀判断是否是PDF
                if (url.endsWith(".pdf")) {
                    Log.d("PDF_URL", "从WebViewClient捕获到PDF链接: " + url);
                    view.loadUrl(googleDocs + url);
                } else {
                    view.loadUrl(url);
                }
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                Log.e("TAG", "错误: " + error.getDescription());
                Toast.makeText(getApplicationContext(), "Oh no! " + error.getDescription(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                dialog.dismiss();
                super.onPageFinished(view, url);
            }
        });

        webView.loadUrl(data);
        webView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }
}

关键修改说明

  • 新增兼容新旧版本的shouldOverrideUrlLoading方法,确保所有链接都被拦截。
  • 新增handlePdfUrl统一处理PDF链接,通过URL后缀判断覆盖远程PDF场景。
  • 在DownloadListener里加入PDF判断,既可以捕获PDF URL,又能选择预览或下载。
  • 修正了webSettings.setLoadsImagesAutomatically(true)的赋值错误(之前只调用了get方法)。
  • 新增setAllowFileAccess和setDomStorageEnabled,确保Google Docs预览功能正常。

内容的提问来源于stack exchange,提问作者ZIBRAN KHAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:13:13