【问题标题】:Does android WebView support <a> tags with download attribute? is there any workaround?android WebView 是否支持带有下载属性的 <a> 标签?有什么解决方法吗?
【发布时间】:2015-12-28 13:15:53
【问题描述】:

所以我有一个 Android 应用程序,它加载一个包含 &lt;a&gt; 这样的标签的 WebView

<a id="download-7630" href="/files/download/7630" download>someFilename.anyExtension</a>

在应用程序后端的上下文中,文件由连接到 mongoDB 的 java 控制器提供服务。我无法更改服务器代码,因此我需要一个解决方法。它们是返回的 GET 请求 GET

ResponseEntity.ok()
            .header("Content-Disposition", "attachment; filename=someFilename.anyExtension")
            .contentLength(file.getLength())
            .contentType(MediaType.parseMediaType(file.getContentType()))
            .body(new InputStreamResource(file.getInputStream()));

我遇到的问题是这个下载标签在浏览器和控制台上运行良好,例如:“资源解释为文档,但使用 MIME 类型应用程序/pdf 传输:“https://XYZDOMAIN/files/download/22306”。但是当我从 WebView 中单击它们时,没有任何事件被触发。

我在 WebViewClient 的shouldOverrideUrlLoading(), onLoadResource(), onPageStarted() and shouldInterceptRequest() 中有调试点,我什么都没有,就像这样形成的标签以某种方式忽略了点击或触摸事件,应用程序中的其他所有内容在 WebView 中都可以正常工作。 (调试点可以正常工作,例如在加载包含链接的站点时,或者在站点中的页面之间导航时)

我的 webView 设置包括:

WebSettings webSettings = mWebView.getSettings();
            webSettings.setJavaScriptEnabled(true);
            webSettings.setSaveFormData(true);
            webSettings.setSavePassword(true);
            webSettings.setDatabaseEnabled(true);
            webSettings.setDomStorageEnabled(true);
            webSettings.setSupportZoom(false);
            webSettings.setAllowFileAccess(true);
            webSettings.setAllowContentAccess(true);
MyWebViewClient myWebViewClient = new MyWebViewClient();
        mWebView.setWebViewClient(myWebViewClient);

MyWebViewClient 只是一个扩展 WebViewClient 的类,我在其中覆盖了我尝试调试的方法

我想要做的是管理服务器发回的文件以启动一个让用户打开文件的意图,但我的问题是我无法拦截任何尝试做的事情那个。

我已经阅读了在 AsyncTasks 中处理下载或添加 DownloadListeners 之类的解决方案,但我的问题是我无法拦截对这些链接(html 标记)的点击。

有什么想法可能是错误的或遗漏的吗?

【问题讨论】:

  • 对不起,这个问题与 HTML5 或 MongoDB 有什么关系?这更像是一个 Android 权限,对吧?
  • 您对 mongoDB 的看法可能是对的,但由于下载属性是 html5 可能是它与我不知道的 WebView 之间的问题,所以我改变了标签...:/
  • 请添加更多答案,mindh's one is not valid
  • @Elkdor 你试过 mWebView.onDownloadListener() 吗?
  • Webview 有一个错误,如果存在下载属性,则阻止锚链接触发操作。见code.google.com/p/android/issues/detail?id=198532

标签: android html android-webview android-download-manager


【解决方案1】:

过去有人报告了 WebView 错误,因此可能存在不支持下载属性宽度“a”标签的 android 版本。
但是,较新版本的 WebView 可以处理下载属性。

这篇文章的代码:Download File inside WebView 完成了这项工作。

wv.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.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed!
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "Name of your downloadble file goes here, example: Mathematics II ");
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File", //To notify the Client that the file is being downloaded
                    Toast.LENGTH_LONG).show();

        }
    });

例如,单击&lt;a href="example.com.file" download&gt;&lt;/a&gt; 不会触发 WebViewClient::onLoadResource。
我明白了,但似乎是一种非常 unjavascript 的行为......

【讨论】:

    【解决方案2】:

    这是浏览器上发生的事情:

    1. 用户点击链接(指向文件)
    2. 浏览器获取该 URL/链接的 HTTP 标头,他们说“这是一个附件”
    3. 浏览器/下载管理器将其视为要下载而不是重定向到的smth

    Webview 可能不知道如何处理下载,不知道如何显示具有此类 Content-Type 标头的内容并且什么都不做。

    你可以做的是:

    1. 在 webview 中拦截重定向(它仍然应该发生,如果 webview 在理解它不能显示任何内容时不显示任何内容)
    2. 您将获得一个网址
    3. 将其识别为指向文件的文件(例如,使用 RegExp)
    4. 在 web 视图之外处理文件下载

    要拦截重定向 URL,您需要:

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

    【讨论】:

    • 谢谢mindeh,我实际上已经尝试过了,但是该链接永远不会调用 shouldOverrideUrlLoading() 我知道该方法有效,因为它确实会因为其他所有内容而被解雇。
    • 对不起,如果我不太清楚......我说我什么都没得到时的意思。我的意思是,当我单击链接时,没有一个调试点会停止提到的任何方法,所以我无法像你建议的那样拦截它。
    • 我猜这可能是 href 作为相对链接的问题,但我似乎找不到可能的解决方法
    • 您也可以尝试此处描述的类似技巧:stackoverflow.com/questions/15176519/… 即检测 JavaScript 中的窗口位置变化,然后调用您的 Java 代码
    猜你喜欢
    • 2021-04-19
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2023-03-31
    • 2016-04-19
    相关资源
    最近更新 更多