我正在开发一个 Android应用程序,其webview指向另一个团队的动态网站. 当我下载一个文件(主要是动态重定向的PDF和ZIP)时,我得到的是下载文件夹中的一个文件,其中包含一些HTML代码,其中包
当我下载一个文件(主要是动态重定向的PDF和ZIP)时,我得到的是下载文件夹中的一个文件,其中包含一些HTML代码,其中包含“用户不允许读取文件”的消息,无论我如何实现下载,我尝试:
> DownloadManager
>意图(让外部浏览器管理下载)
>“手工”(AsyncTask和httpconnection ……)
都具有相同的结果.
使用普通浏览器导航下载工作正常,无论是在台式PC,Android还是iOS设备上.
为什么webview不能访问文件?
可能是一个会话问题? http端口?
我真的需要一些想法……
另一个提示:当从同一个链接下载两次文件时,该链接将重定向到同一个文件,但会产生两个不同的文件名…
编辑:我没有将webView指向网络应用程序,而是试图指向一个带有链接重定向的常见网页来下载另一个文件,好吧,只是它的工作原理.
以下是webview.setDownloadListener – onDownloadStart()参数:
userAgent=Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 contentDisposition=attachment; filename=correct_filename.pdf, url=http://www.xxx.xx/site/downloadfile.wplus?REDIRECTFILE=D-507497120&ID_COUNTOBJ=ce_5_home&TYPEOBJ=CExFILE&LN=2 mimeType=application/octet-stream
这是一些代码
wv.getSettings().setSupportMultipleWindows(true); wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); wv.getSettings().setAllowFileAccess(true); wv.getSettings().setJavaScriptEnabled(true); wv.getSettings().setBuiltInZoomControls(true); wv.getSettings().setDisplayZoomControls(false); wv.getSettings().setLoadWithOverviewMode(true); wv.getSettings().setUseWideViewPort(true); wv.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength){ DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setDescription("Download file..."); request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype)); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed! request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype)); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); dm.enqueue(request); Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show(); } }
编辑二
这是我在尝试“手动”下载文件时使用的代码:
onDownloadStart()是我调用downloadFileAsync()的地方:
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { String fileName; try { fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); downloadFileAsync(url, fileName); }catch (Exception e){ } }
这是AsyncTask:
private void downloadFileAsync(String url, String filename){ new AsyncTask<String, Void, String>() { String SDCard; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { try { URL url = new URL(params[0]); HttpURLConnection urlConnection = null; urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoOutput(true); urlConnection.connect(); int lengthOfFile = urlConnection.getContentLength(); //SDCard = Environment.getExternalStorageDirectory() + File.separator + "downloads"; SDCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+""; int k = 0; boolean file_exists; String finalValue = params[1]; do { if (k > 0) { if (params[1].length() > 0) { String s = params[1].substring(0, params[1].lastIndexOf(".")); String extension = params[1].replace(s, ""); finalValue = s + "(" + k + ")" + extension; } else { String fileName = params[0].substring(params[0].lastIndexOf('/') + 1); String s = fileName.substring(0, fileName.lastIndexOf(".")); String extension = fileName.replace(s, ""); finalValue = s + "(" + k + ")" + extension; } } File fileIn = new File(SDCard, finalValue); file_exists = fileIn.exists(); k++; } while (file_exists); File file = new File(SDCard, finalValue); FileOutputStream fileOutput = null; fileOutput = new FileOutputStream(file, true); InputStream inputStream = null; inputStream = urlConnection.getInputStream(); byte[] buffer = new byte[1024]; int count; long total = 0; while ((count = inputStream.read(buffer)) != -1) { total += count; //publishProgress(""+(int)((total*100)/lengthOfFile)); fileOutput.write(buffer, 0, count); } fileOutput.flush(); fileOutput.close(); inputStream.close(); } catch (MalformedURLException e){ } catch (ProtocolException e){ } catch (FileNotFoundException e){ } catch (IOException e){ } catch (Exception e){ } return params[1]; } @Override protected void onPostExecute(final String result) { } }.execute(url, filename); }
取自How to download a PDF from a dynamic URL in a webview
感谢名单
最后我决定寻找DownloadHandler from the Android Stock Browser code.
我的代码中唯一明显的缺点是cookie(!!!).
这是我的最终工作版本(DownloadManager方法):
wv.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimeType); //------------------------COOKIE!!------------------------ String cookies = CookieManager.getInstance().getCookie(url); request.addRequestHeader("cookie", cookies); //------------------------COOKIE!!------------------------ request.addRequestHeader("User-Agent", userAgent); request.setDescription("Downloading file..."); request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType)); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType)); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); dm.enqueue(request); Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show(); } });