title: Android webview: download files like browsers do
body: <p>I'm working on an Android app with a webview pointing to a dynamic website by another team.<br>
  When i download a file (mostly <strong>dynamically redirected</strong> PDF and ZIP) <strong>all i get is a file in the downloads folder containing some HTML code with a message like "user not allowed to read the file"</strong>, no matter how i implement the download, i tried:<br></p>
  
  <ol>
  <li>DownloadManager<br></li>
  <li>Intent (letting an external browser to manage the download)<br></li>
  <li>"by hand" (AsyncTask and httpconnection...)<br></li>
  </ol>
  
  <p>all with the same results.<br></p>
  
  <p><strong>Navigating with normal browsers downloads work fine, both on desktop PC, android and iOS devices</strong>.</p>
  
  <p><strong>Why webview shouldn't have access to files?</strong></p>
  
  <p>May be a session issue? http port?<br>
  I really need some ideas...<br><br>
  Another tip: when downloading twice a file from the same link, the link will redirect to the same file but resulting in two different filenames...
  <br><br><br>
  <strong>EDIT</strong>: Instead of pointing the webView to the web-app, i tried to point to a common webpage with a link-redirect to download another file, well, simply it works.
  <br><br><br>
  Here are the <code>webview.setDownloadListener - onDownloadStart()</code> parameters:</p>
  
  <pre><code> 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&amp;ID_COUNTOBJ=ce_5_home&amp;TYPEOBJ=CExFILE&amp;LN=2
  
   mimeType=application/octet-stream
  </code></pre>
  
  <p>Here's some code</p>
  
  <pre><code>    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();
          } 
      }
  </code></pre>
  
  <p><br><br>
  <strong>EDIT II</strong><br><br>
  Here's the code i'm using when trying to download files "by hand":</p>
  
  <p>onDownloadStart() is where i call downloadFileAsync():</p>
  
  <pre><code>        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){
  
              }
          }
  </code></pre>
  
  <p>and this is the AsyncTask:</p>
  
  <pre><code>private void downloadFileAsync(String url, String filename){
  
      new AsyncTask&lt;String, Void, String&gt;() {
          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 &gt; 0) {
                          if (params[1].length() &gt; 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);
  }
  </code></pre>
  
  <p>taken from <a href="https://stackoverflow.com/questions/31825957/how-to-download-pdf-from-dynamic-url-in-android-webview">How to download a PDF from a dynamic URL in a webview</a>
  <br>
  Thanx</p>