Android Studio中WebView点击PDF链接无法获取URL的解决方法
解决WebView中PDF链接无法获取及打开的问题
我帮你排查了代码里的几个关键问题,这应该能解决你遇到的PDF链接无法获取、无法正常打开的情况:
问题根源
- 过时的URL拦截方法:你用的
shouldOverrideUrlLoading(WebView view, String url)已经被废弃,Android 7.0+的WebView会优先调用带WebResourceRequest参数的重载方法,导致PDF链接可能没被拦截到。 - PDF链接判断逻辑错误:
URLUtil.isFileUrl(url)只识别file://开头的本地文件链接,但大多数网站的PDF是http/https的远程链接,所以这个判断不会触发Google Docs预览逻辑。 - 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
相关产品推荐
相关产品推荐

