WebView下载适配blob协议

Java无法获得Blob协议的文件流,无法直接处理。不过JavaScript处理Blob协议非常方便,可以考虑通过前端将该文件转化为Base64的字符串。

拦截到下载Blob协议文件时,可以先将链接传给前端,前端通过JS处理后得到Base64的文件流,再将文件流通过Android的JavaScript方法传给客户端。


 1.新建DownloadBlobFileJSInterface

public class DownloadBlobFileJSInterface {
    private static String mimeType = "";
    private static String fileName = "";
    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);
    }

    public static String getBase64StringFromBlobUrl(String blobUrl, String fileMimeType, String urlFileName) {
        if (blobUrl.startsWith("blob")) {
            mimeType = fileMimeType;
            fileName = urlFileName;
            return "javascript: var xhr = new XMLHttpRequest();" + "xhr.open('GET', '" + blobUrl + "', true);" + "xhr.setRequestHeader('Content-type','" + fileMimeType + ";charset=UTF-8');" + "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');";
    }

    private void convertToGifAndProcess(String base64) {
        File gifFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + fileName);
        KLog.d("《《下载请求》》开始保存数据:\n" + base64 + "\n路径:" + gifFile.getPath().toString());
        saveGifToPath(base64, gifFile);
        Toast.makeText(mContext, "保存成功", Toast.LENGTH_SHORT).show();
        insertDownloadFileHistoryDb(fileName);
        if (mDownloadGifSuccessListener != null) {
            mDownloadGifSuccessListener.downloadGifSuccess(gifFile.getAbsolutePath());
        }
    }

    private void saveGifToPath(String base64, File gifFilePath) {
        try {
            byte[] fileBytes = Base64.decode(base64.replaceFirst("data:" + mimeType + ";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);
    }

}

2.添加JavaScriptInterface

    binding.mWebview.addJavascriptInterface(new DownloadBlobFileJSInterface(this), "Android");

3.添加WebView下载拦截,并执行JS

 binding.mWebview.setDownloadListener(new DownloadListener() {
            /**
             * @param url  应该下载的内容的完整url
             * @param userAgent 用于下载的用户代理。
             * @param contentDisposition 内容处置http标头(如果存在)。
             * @param mimetype 服务器报告的内容的mimetype
             * @param contentLength  服务器报告的文件大小
             */
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                if (TextUtils.isEmpty(url)) {
                    return;
                }
                if (url.startsWith("blob")) {
                    String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
                    KLog.d("filename:" + fileName);
                    // 3. 执行JS                
binding.mWebview.loadUrl(DownloadBlobFileJSInterface.getBase64StringFromBlobUrl(url, mimetype,fileName));
                    return;
                }
             
               //TODO 其他协议下载方式  http https
            }
        });

你可能感兴趣的:(blob,webview下载)