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