简体   繁体   English

为什么我的下载链接在Android WebView中不起作用?

[英]Why doesn't my download link work in Android WebView?

In my angular 2 application, users can click on a file to download it. 在我的angular 2应用程序中,用户可以单击文件进行下载。 This will get a link from an authenticated web service call, and download it in the browser. 这将从经过身份验证的Web服务调用中获取链接,并将其下载到浏览器中。

It all works fine from a browser (PC, Chrome on Android or whatever). 在浏览器(PC,Android上的Chrome或其他任何浏览器)上都能正常运行。

It doesn't work in an hybrid Android app with a WebView, although I think I did whatever was needed. 尽管我认为我做了所需的一切,但它在带有WebView的混合Android应用程序中不起作用。 It seems that WebViewClient::onLoadResource is never called for the generated link. 似乎从未为生成的链接调用WebViewClient :: onLoadResource。

Here is the relevant part in my angular 2 component: 这是我的角度2组件中的相关部分:

onPathClicked(path:Path) {
    if (path.directory) {
        var newPathEntries = this.appendToPath(this.pathEntries, path.fileName);
        this.searchContents(newPathEntries);
    } else {
        var fileName = path.fileName;
        var pathEntries = this.pathEntries.push(fileName);
        var fullPath = this.buildFullPath(pathEntries);
        this.fileService.getFileDownloadUrl(fullPath)
            .then((url)=> {
                var fileInput:HTMLAnchorElement = <HTMLAnchorElement>document.getElementById('downloadFileLink');
                fileInput.href = url;
                fileInput.setAttribute('download', path.fileName);
                fileInput.click();
            })
            .catch((error)=> {
                this.errorService.showError('Impossible de télécharger le fichier', error);
            });
    }
}

Here is the android part: 这是android部分:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuInflater;
import android.webkit.DownloadListener;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class BlablaActivity extends Activity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xyz_mobile);

        webView = (WebView) findViewById(R.id.webView);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDatabaseEnabled(true);

        WebChromeClient webChromeClient = new WebChromeClient() {
        };
        webView.setWebChromeClient(webChromeClient);

        final DownloadListener downloadListener = new DownloadListener() {
            public void onDownloadStart(String url, String userAgent,
                                        String contentDisposition, String mimetype,
                                        long contentLength) {
                Request request = new Request(Uri.parse(url));
                request.allowScanningByMediaScanner();
                request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "download");

                DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                downloadManager.enqueue(request);

                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); //This is important!
                intent.addCategory(Intent.CATEGORY_OPENABLE); //CATEGORY.OPENABLE
                intent.setType("*/*");//any application,any extension
                Toast.makeText(getApplicationContext(), "Téléchargement", //To notify the Client that the file is being downloaded
                        Toast.LENGTH_LONG).show();
            }
        };
        webView.setDownloadListener(downloadListener);

        WebViewClient webViewClient = new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

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

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                webView.setDownloadListener(downloadListener);
                return true;
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
//                view.loadUrl("file:///android_asset/load_error.html");
//                view.loadData("Erreur : " + error + ". Veuillez vous connecter pour utiliser l'application.", "text/plain", "utf-8");
                showDefaultError();
            }
        };
        webView.setWebViewClient(webViewClient);

        loadJsApp();
    }

    private void loadJsApp() {
        webView.loadUrl("https://www.mymobileapp.com");
    }

    private void showDefaultError() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Erreur");
        builder.setMessage("Désolé, une erreur s'est produite. Veuillez vérifier votre connexion Internet.");

        builder.setIcon(android.R.drawable.ic_dialog_alert);

        AlertDialog dialog = builder.create();
        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                loadJsApp();
            }
        });

        dialog.show();

        //Toast.makeText(this, "Réseau indisponible !", Toast.LENGTH_LONG).show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_xyz_mobile, menu);
        return true;
    }

}

Strangly enough, the 'download' attribute on an HTML anchor element does not seem to be handled correctly in an Android WebView. 不足为奇的是,似乎无法在Android WebView中正确处理HTML锚元素上的“下载”属性。 Removing that attribute should trigger the file download as expected. 删除该属性将触发文件下载,如预期的那样。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM