android - Android WebView - 不能从 WebView 下载文件
问题描述
我使用这个下载监听器
mWebView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDescription,
String mimetype, long contentLength) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String fileName = URLUtil.guessFileName(url,contentDescription,mimetype);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,fileName);
DownloadManager dManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dManager.enqueue(request);
}
});
但是不要在我需要的网站上工作。如果我使用例如这个 url
https://www.sendspace.com/....
文件正常下载。
但如果我使用这个网址
http://m.slovakrail.sk
我买了票,在最后一个网站上我点击下载按钮,但下载不起作用。来自网站的按钮代码是
<input type="submit" name="j_idt91:j_idt93:0:j_idt94" value="Stiahnuť cestovný doklad" class="btn" />
谢谢你的回复。
解决方案
我假设下载表单使用 POST。我发现这样做的唯一方法是使用 注入 JavaScript 代码webView.loadUrl("javascript:...")
,它会从表单中提取所有需要的信息。然后手动执行 POST 请求以下载文件。(例如使用 OkHttp。)
要让DownloadManager
知道下载的文件,您可以使用该downloadManager.addCompletedDownload(...)
方法。
示例代码 (Kotlin)
webView.loadUrl("""
javascript:(function () {
let form = document.querySelector("#form-id");
let inputs = [...form.querySelectorAll("input[type='hidden']")];
form.querySelector("button.pdfLink[type='submit']").addEventListener(
'click',
(e) => {
e.stopPropagation();
e.preventDefault();
App.download(JSON.stringify({
method: form.method,
url: form.action,
fields: inputs.map(f => ({key: f.name, value: f.value}))
}));
},
false);
})()
""".trimIndent())
您还需要将 JS 接口添加到WebView
.
webView.addJavascriptInterface(adapter, "App")
WebView
JS 适配器可能如下所示:
class WebViewJsAdapter {
@JavascriptInterface
fun download(formData: String) {
val data = JSONObject(formData)
// 1. download the file
...
// 2. add the downloaded file to the DownloadManager
// using `downloadManager.addCompletedDownload(...)`
...
}
}
推荐阅读
- php - 在 Woocommerce 存档页面中显示所有产品类型的库存可用性
- c++ - 无法理解链接器在抱怨什么
- youtube - 折旧后的无品牌 YouTube 播放器
- wpf - 使用材料设计 WPF 动态添加控件
- javascript - 当它是字符串的一部分时,尝试根据条件在标签中添加/更改类
- python - 使用 matplotlib.basemap 绘制地图的问题
- google-chrome-extension - 在创建 chrome 扩展程序时,我是否需要获得网站的许可?
- kubernetes - 如何部署到 Kubernetes
- java - ArrayList 项索引不正确:Reversing a ArrayList with Recursion
- java - 将二维整数数组转换为字符串