Android webview: download files like browsers do

前端 未结 5 1652
花落未央
花落未央 2020-11-29 21:33

I\'m working on an Android app with a webview pointing to a dynamic website by another team.
When i download a file (mostly dynamically redirected PDF a

相关标签:
5条回答
  • 2020-11-29 21:39

    With this option I managed to download complete files, the download worked with other options but the documents appeared empty, especially when a session is being used.

    Add below lines to AndroidManifest.xml

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

    Add DownloadListener to your WebView

    Try this code

    wv.setDownloadListener(new DownloadListener() {
        @Override
        public void onDownloadStart(final String url, final String userAgent, String contentDisposition, String mimetype, long contentLength) {
            //Checking runtime permission for devices above Marshmallow.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        == PackageManager.PERMISSION_GRANTED) {
                    Log.v(TAG, "Permission is granted");
                    downloadDialog(url, userAgent, contentDisposition, mimetype);
    
                } else {
    
                    Log.v(TAG, "Permission is revoked");
                    //requesting permissions.
                    ActivityCompat.requestPermissions(PortalActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    
                }
            } else {
                //Code for devices below API 23 or Marshmallow
                Log.v(TAG, "Permission is granted");
                downloadDialog(url, userAgent, contentDisposition, mimetype);
    
            }
        }
    });
    
    //downloadDialog Method
    
    public void downloadDialog(final String url, final String userAgent, String contentDisposition, String mimetype) {
        //getting filename from url.
        final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype);
        //alertdialog
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
    
        //title of alertdialog
        builder.setTitle(R.string.download_title);
        //message of alertdialog
        builder.setMessage(getString(R.string.download_file) + ' ' + filename);
        //if Yes button clicks.
    
        builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //DownloadManager.Request created with url.
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                //cookie
                String cookie = CookieManager.getInstance().getCookie(url);
                //Add cookie and User-Agent to request
                request.addRequestHeader("Cookie", cookie);
                request.addRequestHeader("User-Agent", userAgent);
                //file scanned by MediaScannar
                request.allowScanningByMediaScanner();
                //Download is visible and its progress, after completion too.
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                //DownloadManager created
                DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                //Saving files in Download folder
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
                //download enqued
                downloadManager.enqueue(request);
            }
        });
        builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //cancel the dialog if Cancel clicks
                dialog.cancel();
                mWebView.goBack();
            }
    
        });
        //alertdialog shows.
        builder.show();
    
    }
    
    0 讨论(0)
  • 2020-11-29 21:42

    Finally i decided to look for the DownloadHandler from the Android Stock Browser code. The only noticeable lack in my code was cookie (!!!).

    Here's my final working version (DownloadManager method):

        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.setMimeType(mimeType);
                //------------------------COOKIE!!------------------------
                String cookies = CookieManager.getInstance().getCookie(url);
                request.addRequestHeader("cookie", cookies);
                //------------------------COOKIE!!------------------------
                request.addRequestHeader("User-Agent", userAgent);
                request.setDescription("Downloading file...");
                request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType));
                request.allowScanningByMediaScanner();
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType));
                DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                dm.enqueue(request);
                Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();
            }
        });
    
    0 讨论(0)
  • 2020-11-29 21:49

    Just to note - you also should add "Referer" request header - without it some sites simply will not let you to download files.

    0 讨论(0)
  • 2020-11-29 21:59
    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.setMimeType(mimeType);
            //------------------------COOKIE!!------------------------
            String cookies = CookieManager.getInstance().getCookie(url);
            request.addRequestHeader("cookie", cookies);
            //------------------------COOKIE!!------------------------
            request.addRequestHeader("User-Agent", userAgent);
            request.setDescription("Downloading file...");
            request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType));
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType));
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();
        }
    });
    

    thanks j.c for your answer you missed ); at end of code..

    0 讨论(0)
  • 2020-11-29 21:59

    also you can use :

    mWebView.setDownloadListener(new DownloadListener() {
    public void onDownloadStart(String url, String userAgent,
                String contentDisposition, String mimetype,
                long contentLength) {
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(Uri.parse(url));
        startActivity(i);
    }});
    
    0 讨论(0)
提交回复
热议问题