为什么下载属性不适用于Lollipop的网络视图?

时间:2015-06-28 08:02:50

标签: android html5 android-webview

在我启用了javascript的Android Lollipop网页视图中,我尝试让用户使用<a>的下载属性下载一个简单的文件 hello.txt :< / p>

// Store some text in a data URL.
var dataUrl = (window.URL || window.webkitURL).createObjectURL(
    new Blob(["Hello world. :)"]));

// Create a link that lets the user download the text file as hello.txt.
var downloadLink = document.createElement('a');
downloadLink.setAttribute('href', dataUrl);
downloadLink.setAttribute('download', 'hello.txt');
downloadLink.innerHTML = 'Click to download hello.txt.';

// Display the link.
document.getElementById('container').appendChild(downloadLink);

这适用于桌面 - 尝试点击this Fiddle中的链接。

但是,单击Web视图中的链接不会执行任何操作。为什么?我是否需要以某种方式为Android Web视图启用下载?

我尝试创建自定义Web视图客户端无济于事:

    package com.somesideprojects;

    import android.app.Activity;
    import android.app.DownloadManager;
    import android.content.Context;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    import android.util.Log;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;


    /**
     * Web view client that allows for downloads.
     */
    public class CustomWebViewClient extends WebViewClient {
        private Activity currentActivity;

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
            Log.d("WEB_VIEW_TEST", "error code:" + errorCode + " - " + description);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // Download any requested text files.
                Uri source = Uri.parse(url);
                String fileName = url;

                // Make a new request pointing to the file url.
                DownloadManager.Request request = new DownloadManager.Request(source);

                // Appears the same in Notification bar while downloading
                request.setDescription("Downloading " + fileName + " to your downloads directory.");
                request.setTitle(fileName);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    request.allowScanningByMediaScanner();
                    request.setNotificationVisibility(
                            DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                }
                // Save the file to the "Downloads" folder of SDCARD
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

                // Get the download service and enqueue file.
                DownloadManager manager = (DownloadManager) this.currentActivity.getApplication()
                        .getSystemService(Context.DOWNLOAD_SERVICE);
                manager.enqueue(request);
            return true;
        }

        /**
         * Sets the current activity.
         * @param currentActivity Sets the current active activity. Set during onResume.
         */
        public void setCurrentActivity(Activity currentActivity) {
            this.currentActivity = currentActivity;
        }
    }

我也尝试创建自己的下载监听器,这也没有效果。

package com.somesideprojects;

import android.webkit.DownloadListener;


/**
 * A download listener that lets users download files from the web view.
 */
public class CustomDownloadListener implements DownloadListener {

    private MainActivity currentActivity;

    @Override
    public void onDownloadStart(
            String url,
            String userAgent,
            String contentDisposition,
            String mimeType,
            long contentLength) {
        android.util.Log.d("Logger",
                "url : " + url +
                " userAgent: " + userAgent +
                " contentDisposition: " + contentDisposition +
                        " mimeType: " + mimeType + " contentLength " + contentLength);

        android.net.Uri source = android.net.Uri.parse(url);

        // Make a new request.
        android.app.DownloadManager.Request request =
                new android.app.DownloadManager.Request(source);

        // Appears the same in notification bar while downloading.
        String filename = getFilename(contentDisposition);

        request.setDescription(
                "This project will be saved in your downloads folder as " + filename + ".");
        request.setTitle(filename);

        // Add cookie on request header (for authenticated web app).
        String cookieContent = getCookieFromAppCookieManager(source.getHost());
        request.addRequestHeader("Cookie", cookieContent);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(
                    android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        }

        // Save the file in the "Downloads" folder of SDCARD.
        request.setDestinationInExternalPublicDir(
                android.os.Environment.DIRECTORY_DOWNLOADS, filename);

        // Get the download service and enqueue the file.
        android.app.DownloadManager manager =
                (android.app.DownloadManager) this.currentActivity.getApplication()
                        .getSystemService(android.content.Context.DOWNLOAD_SERVICE);

        manager.enqueue(request);
    }

    public String getFilename(String contentDisposition){
        String filename[] = contentDisposition.split("filename=");
        return filename[1].replace("filename=", "").replace("\"", "").trim();
    };

    public String getCookieFromAppCookieManager(String url){
        android.webkit.CookieManager cookieManager = android.webkit.CookieManager.getInstance();
        if (cookieManager == null) {
            return null;
        }
        String rawCookieHeader = null;

        // Extract Set-Cookie header value from Android app CookieManager for this URL
        rawCookieHeader = cookieManager.getCookie(url);
        if (rawCookieHeader == null) {
            return null;
        }

        return rawCookieHeader;
    };

    public void setCurrentActivity(MainActivity currentActivity) {
        this.currentActivity = currentActivity;
    }
}

这是我的完整权限列表:

<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

1 个答案:

答案 0 :(得分:2)

看起来Android浏览器不支持锚标记的下载属性:( https://code.google.com/p/chromium/issues/detail?id=432414