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
            }
        });

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在WebView中实现移动端适配,您可以采用以下方法: 1. 使用CSS媒体查询:通过在WebView加载的网页中使用CSS媒体查询,根据设备的屏幕宽度或设备类型应用不同的样式。您可以根据不同的设备屏幕大小和方向,为不同分辨率的设备提供适当的样式和布局。 2. 使用Viewport元标签:在WebView加载的网页的头部添加Viewport元标签来控制页面在移动设备上的显示。例如,使用以下元标签来设置页面宽度与设备宽度一致,并禁用缩放: ```html <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> ``` 3. 使用rem或vw/vh单位:使用相对单位rem或vw/vh来定义页面元素的尺寸,以便根据设备屏幕大小进行适配。例如,将根元素的字体大小设置为相对于设备宽度的比例,并在样式中使用rem单位来定义其他元素的尺寸。 4. 使用CSS框架或库:考虑使用移动端CSS框架或库(如Bootstrap、Vant等),这些框架提供了响应式布局和移动端样式组件,可以方便地进行移动端适配。 请注意,WebView加载的网页中的CSS和JavaScript代码可能需要根据具体情况进行调整和优化,以确保在不同设备上获得良好的用户体验。 以上是一些常用的方法来实现WebView页面的移动端适配。根据您的具体需求和开发情况,可以选择合适的方法来适应不同的移动设备。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值