Android Web Browsing: Downloading Files, such as Browsers

I am working on an Android app with a webview pointing to a dynamic website by another team.
When I upload a file (mostly dynamically redirected PDF and ZIP), all I get is a file in the download folder containing some HTML code with a message like "user did not allow the file to be read" , regardless of how I implement the download, I tried:

  • Downloadmanager
  • Intent (allowing an external browser to control downloads)
  • "manually" (AsyncTask and httpconnection ...)

all with the same results.

Navigating with normal browser downloads works great on both desktop PCs and Android and iOS devices .

Why web browsing should not have access to files?

Could there be a problem with the session? port http?
I really need ideas ...

Another tip: when you download a file twice from the same link, the link will be redirected to the same file, but the result will be two different file names ...


EDIT . Instead of pointing the webView to a web application, I tried pointing to a shared web page with link migration to load another file, well, it just works.


Here are the parameters for 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 

Here is some 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(); } } 



EDIT II

Here is the code that I use when trying to upload files β€œmanually”:

onDownloadStart () is where I call 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){ } } 

and this is 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); } 

taken from How to load a PDF file from a dynamic URL in a web browser
Thanx

+14
android download webview permissions
source share
4 answers

Finally, I decided to look for DownloadHandler from the Android Stock Browser code . The only noticeable flaw in my code was cookie (!!!).

Here is my latest working version (DownloadManager method):

  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(); } }); 
+41
source share
 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(); } }); 

thanks jc for your answer you missed ); at the end of the code.

+1
source share

With this option, I was able to download complete files, the download worked with other options, but the documents looked empty, especially when using a session.

Add the lines below to AndroidManifest.xml

 <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

Add DownloadListener to your WebView

Try this code

 wv.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(final String url, final String userAgent, String contentDisposition, String mimetype, long contentLength) { //Checking runtime permission for devices above Marshmallow. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.v(TAG, "Permission is granted"); downloadDialog(url, userAgent, contentDisposition, mimetype); } else { Log.v(TAG, "Permission is revoked"); //requesting permissions. ActivityCompat.requestPermissions(PortalActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } } else { //Code for devices below API 23 or Marshmallow Log.v(TAG, "Permission is granted"); downloadDialog(url, userAgent, contentDisposition, mimetype); } } }); //downloadDialog Method public void downloadDialog(final String url, final String userAgent, String contentDisposition, String mimetype) { //getting filename from url. final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype); //alertdialog AlertDialog.Builder builder = new AlertDialog.Builder(this); //title of alertdialog builder.setTitle(R.string.download_title); //message of alertdialog builder.setMessage(getString(R.string.download_file) + ' ' + filename); //if Yes button clicks. builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //DownloadManager.Request created with url. DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); //cookie String cookie = CookieManager.getInstance().getCookie(url); //Add cookie and User-Agent to request request.addRequestHeader("Cookie", cookie); request.addRequestHeader("User-Agent", userAgent); //file scanned by MediaScannar request.allowScanningByMediaScanner(); //Download is visible and its progress, after completion too. request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //DownloadManager created DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); //Saving files in Download folder request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); //download enqued downloadManager.enqueue(request); } }); builder.setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //cancel the dialog if Cancel clicks dialog.cancel(); mWebView.goBack(); } }); //alertdialog shows. builder.show(); } 
+1
source share

AsyncTask for manually loading the file name (you can add additional code to this class):

 private static class getFileNameAsync extends AsyncTask<String, Void, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { URL url; String filename = null; HttpURLConnection conn = null; try { url = new URL(params[0]); conn = (HttpURLConnection) url.openConnection(); conn.connect(); conn.setInstanceFollowRedirects(false); try { for(int i = 0; i < 100; i++) { String stringURL = conn.getHeaderField("Location"); if (stringURL != null) { url = new URL(stringURL); conn = (HttpURLConnection) url.openConnection(); conn.connect(); conn.setInstanceFollowRedirects(false); } else { i = 100; } } } catch (Exception e) { e.printStackTrace(); } String depo = conn.getHeaderField("Content-Disposition"); if (depo != null) { String depoSplit[] = depo.split(";"); int size = depoSplit.length; for(int i = 0; i < size; i++) { if(depoSplit[i].startsWith("filename=")) { filename = depoSplit[i].replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1").trim(); i = size; } } } } catch (MalformedURLException e){ e.printStackTrace(); } catch (ProtocolException e){ e.printStackTrace(); } catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); } finally { if (conn != null) conn.disconnect(); } return filename; } @Override protected void onPostExecute(String filename) { super.onPostExecute(filename); } } 

DownloadListener (stable version, do not change it):

  mWebView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { if(Build.VERSION.SDK_INT >=23){ Context nContext = MainActivity.this.getApplicationContext(); if(nContext.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ MainActivity.this.requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); return; } } String fileName = ""; url = url.replace(" ", "%20"); AsyncTask<String, Void, String> asyncTask = new getFileNameAsync(); asyncTask.execute(url); try { fileName = asyncTask.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (CancellationException e) { e.printStackTrace(); } if ((fileName == null) || (fileName.hashCode() == "".hashCode())) { fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); } DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setMimeType(mimetype); String cookies = CookieManager.getInstance().getCookie(url); request.addRequestHeader("Cookie", cookies); request.addRequestHeader("User-Agent", userAgent); request.setDescription("Downloading File"); request.setTitle(fileName); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); if (downloadManager != null) { downloadManager.enqueue(request); } Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show(); } }); 
0
source share

All Articles