Xamarin Android WebView download file does nothing - android

I have a webview that shows a website which i did not make so i dont know the details of how it works.
On this site there are several buttons which download various files which are generated on the fly. Here is an example of the url request used on one of these buttons: test.example.com/Test/Export/Stuff?format=Pdf
This causes a file to be downloaded on my desktop browser and on my phones chrome but nothing happens on my app.
I have scoured the internet searching for a solution but i am unable to find one that works.
I have tried setting DownloadListener as discribed here: https://forums.xamarin.com/discussion/4605/download-file-by-webview but the OnDownloadStart never triggers.
I have also tried intercepting the url request using ShouldOverrideUrlLoading in my custom WebViewClient as descibed in other posts with no luck.
Here is the html code for the button:
<input id="exportPdfButton" class="secondary hover" format="Pdf" value="Download (PDF)" name="exportPdfButton" type="submit">
<script id="dxss_848651839" type="text/javascript">
<!--
var dxo = new MVCxClientButton('exportPdfButton');
dxo.InitGlobalVariable('exportPdfButton');
dxo.SetProperties({'autoPostBack':true,'isNative':true});
dxo.SetEvents({'Click':ExportButtonOnClick});
dxo.AfterCreate();
//-->
</script>
I have set permissions for ACCESS_DOWNLOAD_MANAGER, WRITE_EXTERNAL_STORAGE etc.
Can anyone help me figure out how i can download these files in the app? Otherwise is there any other information i can provide to help?

Can anyone help me figure out how i can download these files in the app?
Firstly, please make sure your WebView has enabled javascript and the WebViewClient is set correctly:
mWebview = FindViewById<WebView>(Resource.Id.mWebview);
mWebview.Download += MWebview_Download;
var client = new WebViewClient();
mWebview.Settings.JavaScriptEnabled = true;
mWebview.SetWebViewClient(client);
mWebview.LoadUrl("your url");
Then in the WebView.Download event use DownloadManager to download the file:
private void MWebview_Download(object sender, DownloadEventArgs e)
{
var url = e.Url;
DownloadManager.Request request = new DownloadManager.Request(Uri.Parse(url));
request.AllowScanningByMediaScanner();
request.SetNotificationVisibility(DownloadManager.Request.VisibilityVisibleNotifyCompleted); //Notify client once download is completed!
request.SetDestinationInExternalPublicDir(Environment.DirectoryDownloads, "CPPPrimer");
DownloadManager dm = (DownloadManager)GetSystemService("download");
dm.Enqueue(request);
Toast.MakeText(ApplicationContext, "Downloading File",ToastLength.Long//To notify the Client that the file is being downloaded
).Show();
}

Related

Android webview not generating pdf report on button click

I have created a web app in Android studio using WebView. I have loaded a WordPress site in android WebView. The WordPress site exports a pdf report on a button click When i load it on chrome browser.
The website loaded in chrome
When i click on PDF button shows the window
and
and finally it starts downloading the pdf file
and the generated pdf report looks like:
But the problem occurs when i use the Android App created in WebView. When i click on PDF button it does nothing and i get a Debug log
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: true
[InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
I have manifest permission set to
uses-permission android:name="android.permission.INTERNET"
Code here
private static final String WEB_URL = "http://workmanager.midzonetechnologies.com/";
webView = findViewById(R.id.webView);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setAllowContentAccess(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setBlockNetworkLoads(false);
webView.getSettings().setAppCacheMaxSize( 10 * 1024 * 1024 ); // 10MB
webView.getSettings().setAppCachePath(getApplicationContext().getCacheDir().getAbsolutePath() );
webView.getSettings().setAllowFileAccess( true );
webView.getSettings().setAppCacheEnabled( true );
webView.getSettings().setJavaScriptEnabled( true );
webView.getSettings().setCacheMode( WebSettings.LOAD_DEFAULT );
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(WEB_URL);
Please tell is the problem related to manifest file permission or run time permission, Please give a solution.
The Android app that i created in WebView.
What you are seeing happening in Chrome is:
noticing the downloadable file based on path: mywebsite.com/randomPath/randomFile**.pdf**
request download permissions
download the file to it's local storage
open the PDF file using Google Drive
If you want that behaviour you have to code all those steps in your app.
A fast solution to this is to intercept the url, check if it is a pdf file and then use a browser to open it.
webView.webviewClient = object : WebViewClient() {
#TargetApi(Build.VERSION_CODES.N)
fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest): Boolean {
val url = request.url.toString()
if (url.takeLast(4) == ".pdf") {
startActivity(
Intent(
Intent.ACTION_VIEW,
"https://docs.google.com/gview?embedded=true&url=${request.url}"
)
)
return true
}
return false
}
}
You would probably have to have different steps in here. As #Florin T. stated, you would first have to get the Permission required for your App:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In the next step you would be detect wether the system can be downloading anything.
This coud be done like so:
mWebView.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}});
Source here
If you then click on the PDF-Button in your WebView, the system should be handling the download on your phone. This means that you can then be opening your download as if it would have been downloaded via chrome.
In the last step, you would have to get the saved loaction from the download and start an Intent to open it with a local PDF-App. This could be done via android intents.

Android WebView throws "cross origin requests are only supported for http" exception while trying to load resource from disk

i have developed a single page game in html/js and am trying to host it inside an android webview. i have a folder src/main/assets/www/ and this line of code to bootstrap my app:
mWebView.loadUrl("file:///android_asset/www/index.html");
the index.html loads a app.js file which is my game. when i try to make an xhr request from within app.js to get assets/myimage.svg (physical location src/main/assets/www/assets/myimage.svg) :
var xhr = new XMLHttpRequest();
xhr.open('get', 'assets/myimage.svg', true);
xhr.send();
I get this error: cross origin requests are only supported for http. why is this a cross-origin request? what can i do to fix this? i cannot host the svg on a http webserver and cannot inline it in app.js - it has to be loaded from disk.
Not sure but you can try these steps and see if it helps:
a) Initialize your WebView:
b) get WebView settings:
WebSettings settings = _webView.getSettings();
c) set following settings:
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);
d) now you can load your your html file by standard way:
mWebView.loadUrl("file:///android_asset/www/index.html");
e) Don't forget to add the internet permission in your manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
If you are looking for the same problem with Android, but using Xamarin/C#
var webView = FindViewById<WebView>(Resource.Id.webView);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.AllowFileAccessFromFileURLs = true;
webView.Settings.AllowUniversalAccessFromFileURLs = true;
webView.LoadUrl("file:///android_asset/www/index.html");

POST to Android Webview where the response is a PDF file

I am performing a POST to the Android webview where the expected response is a PDF file. However the webview just shows a blank page. I realise that PDF files cannot be rendered in the webview but would expect the file to start downloading or show some response at least.
Does anyone know if its possible to POST to a webview to initiate download of a (pdf) file?
_webView = FindViewById<WebView>(Resource.Id.ebookWebview);
_webView.SetWebViewClient(webviewClient);
_webView.SetWebChromeClient(new WebChromeClient());
_webView.Settings.AllowFileAccess = true;
_webView.Settings.JavaScriptEnabled = true;
_webView.PostUrl(_postUrl, EncodingUtils.GetBytes(_postData, "BASE64"));
Have you tried registering a DownloadListener on the WebView? That is needed to handle the download. Please see http://developer.android.com/reference/android/webkit/WebView.html#setDownloadListener(android.webkit.DownloadListener)

how to display pdf from localhost

In my application i need to display pdf files.
I tried to display in webview using google docs. My problem is pdf files are stored in localhost. when give this localhost url its not working. But other all urls are works fine. I checked my localhost url in browser its work fine. I can't able to see in my application.
It shows like this
" Sorry, we were unable to find the document at the original source.Verify that document still exits. you can also try to download the original document by clicking here "
My code
runOnUiThread(new Runnable() {
public void run() {
WebView mWebView=new WebView(PdfFiles.this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginsEnabled(true);
String PdfUrl = "http://10.0.2.2/moodle/practice/document/"+Pdfname;
mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+PdfUrl);
//"http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_open_parameters.pdf"
//mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+"http://www.ztsinc.com/MBT1_OI.pdf");
//mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+"http://www.ourwebsite/path"+lvForDialog.getItemAtPosition(position));
setContentView(mWebView);
}
});

Downloading a file to Android WebView (without the download event or HTTPClient in the code)

This is more a question out of curiosity than a real problem that needs to be solved. I made an Android app which contains a WebView. I used the should override URL method so that any link clicked would be opened in the WebView.
Later I decided that a file would be downloaded from the server to the user device. Unfortunately I had not seen the setDownloadListener method before. When the user clicks a link now the download is not initiated.
As far as I can tell I need to update the app with proper code i.e the download listener or a HttpClient, which is okay.
(At the risk of sounding like an idiot) I am wondering, is there any way through an action from the server that I can make the WebView download a file without a code change?
I guess that functionality is not in the WebView which is probably why the WebView opens a browser to download a file. Just thinking maybe I have missed something to make it work. I am pretty new to this.
You should be able to fire a download with DownloadManager in android via a webview JavascripInterface. I am trying this myself with no success so far. I probably have issues with the context in which the webview and DownloadManager are working. I will come back with some code if it's going to work :)
UPDATE:
The following code works very well for me. You can use something like: (just beaware you can only use DownloadManager from Android 2.3+)
myWebView.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
Log.d("WEB_VIEW_TEST", "error code:" + errorCode + " - " + description);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// handle different requests for different type of files
// this example handles downloads requests for .apk and .mp3 files
// everything else the webview can handle normally
if (url.endsWith(".apk")) {
Uri source = Uri.parse(url);
// Make a new request pointing to the .apk url
DownloadManager.Request request = new DownloadManager.Request(source);
// appears the same in Notification bar while downloading
request.setDescription("Description for the DownloadManager Bar");
request.setTitle("YourApp.apk");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
// save the file in the "Downloads" folder of SDCARD
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "SmartPigs.apk");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
else if(url.endsWith(".mp3")) {
// if the link points to an .mp3 resource do something else
}
// if there is a link to anything else than .apk or .mp3 load the URL in the webview
else view.loadUrl(url);
return true;
}
});
In the above code I manage links to .apk files, .mp3 files and all the other links will be handled by the webview (normal HTML pages)
I think webview will download and render only text/html contents and the multiparts. And the rest will be directed to a download client which you are seeing.
Herojit

Categories

Resources