Reputation: 1379
I have a specific scenario where I make a POST
request with a unique ticket in the body to get a resulting page back.
The resulting page is either Content-Type
: application/pdf
or text/html
.
The ticket is only valid once, so the page can only be loaded once.
Problem is that Android WebView does not support rendering of pdf (as the equivalent on iOS do).
I've tried the following:
Check http response headers with a primary request and then download the file with a second request if it's a pdf and open it in a PDF app (works). But for loading html pages, the second request fails, since the ticket is no longer valid.
Download both the pdf and the html page and then open in pdf app/WebView locally. This works, both relative links in the web pages is broken. Is there a nice way to download them as well?
x. Is it possible to interrupt the request in the WebView to read the response headers and trigger a download if it's a pdf otherwise just continue rendering? Can't find a good answer for this.
Upvotes: 1
Views: 3020
Reputation: 11873
You can use the built in method URLConnection.getContentType() for the exact purpose. Once you get the content type proceed with downloading or pass to the WebView
.
Imports:
import java.net.URL;
import java.net.URLConnection;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
Here's a sample to intercept the URL before loading:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String requestedUrl = request.getUrl().toString();
boolean isDownloadableFile = false;
try {
isDownloadableFile = new FetchContentTypeAsync(requestedUrl).execute().get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
// downloadable file / dont load it in webview
if (isDownloadableFile) {
// download the file here
return false;
} else {
// non downloadable file / load it in webview
view.loadUrl(requestedUrl);
return super.shouldOverrideUrlLoading(view, request);
}
}
});
FetchContentTypeAsync is used for running the task in background
private static class FetchContentTypeAsync extends AsyncTask<Void, Void, Boolean> {
private String requestedUrl;
FetchContentTypeAsync(String requestedUrl) {
this.requestedUrl = requestedUrl;
}
@Override
protected Boolean doInBackground(Void... voids) {
boolean isDownloadableFile = false;
try {
URL url = new URL(requestedUrl);
URLConnection urlConnection = url.openConnection();
String contentType = urlConnection.getContentType();
isDownloadableFile = contentType.equalsIgnoreCase("application/pdf");
} catch (IOException e) {
e.printStackTrace();
}
return isDownloadableFile;
}
}
To download a file check Download a file with Android, and showing the progress in a ProgressDialog
Upvotes: 4
Reputation: 121
After you set the WebViewClient it has some interfaces to intercept the requests the most widely used is shouldOverrideUrlLoading()
but you can also override shouldInterceptRequest()
and intercept it there.
webView.setWebViewClient(new WebViewClient() {
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Check the URL here - if it is a file,
// then initiate the download
return false;
}
}
Upvotes: 0