This method is only suitable for downloading small files such as images. Excessive files will cause memory overflow and crash

Android does not support bloB protocol, but front-end support, can let the front end of the file into base64 format file transfer to us, of course, we can also implement, implementation code is as follows:

public static class DownloadBlobFileJSInterface {

        private Context mContext;
        private DownloadGifSuccessListener mDownloadGifSuccessListener;

        public DownloadBlobFileJSInterface(Context context) {
            this.mContext = context;
        }

        public void setDownloadGifSuccessListener(DownloadGifSuccessListener listener) {
            mDownloadGifSuccessListener = listener;
        }

        @JavascriptInterface
        public void getBase64FromBlobData(String base64Data) {
            convertToGifAndProcess(base64Data);
        }

        /** * insert js code, convert to base64 *@paramBlobUrl The obtained URL *@return* /
        public static String getBase64StringFromBlobUrl(String blobUrl) {
            if (blobUrl.startsWith("blob")) {
                return "javascript: var xhr = new XMLHttpRequest();" +
                        "xhr.open('GET', '" + blobUrl + "', true);" +
                        "xhr.responseType = 'blob';" +
                        "xhr.onload = function(e) {" +
                        " if (this.status == 200) {" +
                        " var blobFile = this.response;" +
                        " var reader = new FileReader();" +
                        " reader.readAsDataURL(blobFile);" +
                        " reader.onloadend = function() {" +
                        " base64data = reader.result;" +
                        " Android.getBase64FromBlobData(base64data);" +
                        "}" +
                        "}" +
                        "}; +
                        "xhr.send();";
            }
            return "javascript: console.log('It is not a Blob URL');";
        }

        /**
         * 转换成file
         * @param base64
         */
        private void convertToGifAndProcess(String base64) {
            File gifFile = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOWNLOADS) + "/" + fileName);
            saveFileToPath(base64, gifFile);
            if(mDownloadGifSuccessListener ! =null) { mDownloadGifSuccessListener.downloadGifSuccess(gifFile.getAbsolutePath()); }}/** * Save the file *@param base64
         * @param gifFilePath
         */
        private void saveFileToPath(String base64, File gifFilePath) {
            try {
                byte[] fileBytes = Base64.decode(base64.replaceFirst(
                        "data:image/gif; base64,".""), 0);
                FileOutputStream os = new FileOutputStream(gifFilePath, false);
                os.write(fileBytes);
                os.flush();
                os.close();
            } catch(Exception e) { e.printStackTrace(); }}public interface DownloadGifSuccessListener {
            void downloadGifSuccess(String absolutePath); }}Copy the code

Configuration of the webview

mWebSettings.setJavaScriptEnabled(true);

mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true); 

mDownloadBlobFileJSInterface = new DownloadBlobFileJSInterface(this);

webView.addJavascriptInterface(mDownloadBlobFileJSInterface, "Android");

mDownloadBlobFileJSInterface.setDownloadGifSuccessListener(absolutePath -> Toast.makeText(MainActivity.this."Download successfully, under Download directory",Toast.LENGTH_SHORT).show());

webView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> {
            webView.loadUrl(DownloadBlobFileJSInterface.getBase64StringFromBlobUrl(url));
        });
      
Copy the code

The file name and format of the download need to determine their own, this method can only download but not determine the format and file name