WebView loads url more than a time in android - android

webview in android loads more than once while loading the url.
Below is the code.
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url.contains(".pdf")) {
String[] spliturl = url.split("http://someurl/");
String googleurl = "http://docs.google.com/viewer?embedded=true&url=";
System.out.println("Google Url"+googleurl);
System.out.println("spliturl"+spliturl[1]);
view.loadUrl(googleurl+spliturl[1]);
}
else
view.loadUrl(url);
return true;
}
});
I am splitting the url as it contains more than one url to be passed on google document viewer for rendering the pdf document.
First time the url is correctly split and the url is concatenated to open in google docs but the webview executes again there by giving an ArrayIndexOutOfBoundsException at spliturl[1].
Could anybody let me know why is this executing again.
thanks.

I don't know why it gets called multiple times, but the solution is to handle it in onPageStarted rather than in shouldOverrideUrlLoading
boolean calledOnce=false;
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (url.contains(".pdf") && !calledOnce) {
String[] spliturl = url.split("http://someurl/");
String googleurl = "http://docs.google.com/viewer?embedded=true&url=";
System.out.println("Google Url"+googleurl);
System.out.println("spliturl"+spliturl[1]);
url = googleurl+spliturl[1];
calledOnce = true;
}
super.onPageStarted(view, url, favicon);
}

You should always check if an array has a size more than the index requested:
if (url.contains(".pdf") && url.split("http://someurl/").size()>2){
// your code
}
Don't know why it gets called though - probably multiple redirections.

Related

How is shouldOverrideUrl called

I'm totally new to android development.
Recently I'm asked to investigate something about webview loading for our app which is written by flutter, and used flutter_webview_plugin.
After I version up flutter_webview_plugin, I find there are some changes.
And there is the code in flutter_webview_plugin
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Map<String, Object> data = new HashMap<>();
data.put("url", url);
data.put("type", "startLoad");
FlutterWebviewPlugin.channel.invokeMethod("onState", data);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Map<String, Object> data = new HashMap<>();
data.put("url", url);
FlutterWebviewPlugin.channel.invokeMethod("onUrlChanged", data);
data.put("type", "finishLoad");
FlutterWebviewPlugin.channel.invokeMethod("onState", data);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
// returning true causes the current WebView to abort loading the URL,
// while returning false causes the WebView to continue loading the URL as usual.
String url = request.getUrl().toString();
boolean isInvalid = checkInvalidUrl(url);
Map<String, Object> data = new HashMap<>();
data.put("url", url);
data.put("type", isInvalid ? "abortLoad" : "shouldStart");
FlutterWebviewPlugin.channel.invokeMethod("onState", data);
return isInvalid;
}
I tried to search everywhere by using shouldOverrideUrlLoading, onPageStarted,onPageFinished, but can't find where they are called.
I think they should be used by like:
BrowserClient webViewClient;
webviewClient.shouldOverrideUrlLoading()
or
webViewClient.invokeMethod('shouldOverrideUrlLoading',arg)
something like above. But I can't find anything.
The WebView calls these methods itself when a page is supposed to be loaded.
So let us say the WebView is trying to load www.google.com, the method shouldOverrideUrlLoading will get a call with the web address www.google.com passed in to the request argument.
You can return true or false to tell the WebView whether it should load the url, or if it should stop it.
A common use case is to prevent the user from navigating away from a specific webpage in a in app browser.
Hope this helps!!

Unable to open google play store from android webview

I am opening a url in android webview which is redirecting the user to google play store web page in android webview and play store page is showing OPEN IN PLAY STORE APP
and while clicking that button rather then opining play store app webview is redirecting to a web url which is not found.
Now i don't know why it is happening as in google chrome app same scenario is working fine. Please suggest the better solution.
Some code i have done :
mWebView.loadUrl("https://play.google.com/store/apps/details?id=in.org.npci.upiapp&hl=en")
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
return super.shouldOverrideUrlLoading(view, urlNewString);
}
#Override
public void onPageFinished(WebView view, String url) {
}
});
Note: I am using this play store url just as an example.
You need to override shouldOverrideUrlLoading, but you must also inspect the URL and conditionally create an intent if it starts with the intent:// scheme. We (the Android WebView team) have written a sample application which does precisely this.
Just put this data in the webview:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && url.startsWith("https://play.google.com/store/apps/developer?id=putyourplaystoreid")) {
Intent i = new Intent("android.intent.action.VIEW");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setData(Uri.parse(url));
startActivity(i);
return true;
} else {
return false;
}
}

android webview measure times of all resources

It is possible to measure the load time of all the resources of a webview?
For example for loading the complete web, I use:
public void onPageStarted(WebView view, String url, Bitmap favicon) {
startingTime = System.currentTimeMillis();
super.onPageStarted(view, url, favicon);
}
public void onPageFinished(WebView view, String url) {
timeElapsed = System.currentTimeMillis() - startingTime;
super.onPageFinished(view, url);
}
but to measure the load of CSS, images, etc. I use
public HashMap<String, Long> resources = new HashMap<String, Long>();
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request){
resources.put(request.getUrl().toString(), System.currentTimeMillis());
WebResourceResponse response = super.shouldInterceptRequest(view, request);
return response;
}
public void onLoadResource(WebView view, String url) {
if(resources.containsKey(url)){
Long timeStartResource = resources.get(url);
Long timeElapseResource = System.currentTimeMillis() - timeStartResource;
}
super.onLoadResource(view, url);
}
I thought the onLoadResource method is executed when the resource was loaded but according to documentation
public void onLoadResource (WebView view, String url).
Notify the host application that the WebView will load the resource specified by the given url.
And
public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
Notify the host application of a resource request and allow the application to return the data. If the return value is null, the WebView will continue to load the resource as usual. Otherwise, the return response and data will be used.
Both they run before loading the resource. Is there any way to measure these times?
There is a great HTML5 API for that accessible to your page. See http://www.sitepoint.com/introduction-resource-timing-api/
Starting from KitKat, WebView is based on Chromium, which supports this API. To check that, open remote web debugging for your app (assuming that you have enabled JavaScript for your WebView), and try evaluating in console:
window.performance.getEntriesByType('resource')
You will get an array of PerformanceResourceTiming objects for each resource your page has loaded.
In order to transport your information to Java side, you can use an injected Java object.
That you can done using onPageFinished() and answer of this question is already given description here.

How to alter URL loading in a webview?

The basic idea is to alter every url being loaded in a webview (for example adding/removing get parameters).
I have a custom WebViewClient, in which I have the following method :
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String modifiedUrl = Util.someMethod(url);
super.shouldOverrideUrlLoading(view, modifiedUrl);
}
Will it work or should I put this logic in another method, for example onPagestarted ?
You rather should do something like :
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(conditionForModifyingUrl){
String modifiedUrl = Util.someMethod(url);
view.loadUrl(modifiedUrl);
return true;
}
return false;
}
Calling super.shouldOverrideUrlLoading(view, modifiedUrl) won't work because, as it is its name, this method only checks if the url should be overridden, and does not load the url at all.

WebViewClient shows white screen

I'm new to Android app development.
I'm managing to show a WebView and load a given URL. When I click on a link in the WebView, I get a blank white screen.
When I use the Chrome browser on the device (Galaxy TAB), it's working. Actually i'm trying to imitate Chrome in my WebView.
Does anyone know what's the problem?
This is the WebViewClient I use in my WebView:
siteView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
siteView.loadUrl(urlNewString);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (dialog == null || !dialog.isShowing()) {
if(isFirstTime) {
dialog = ProgressDialog.show(MyActivity.this, "", getString(R.string.loadingMessage), true, false);
MyActivity.isFirstTime = false;
}
}
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
});
try siteView.invalidate()
before loading anything to webview
The problem may lie in your shouldOverrideUrlLoading function. Your are receiving "view" as a parameter and you using "siteView" to load url. Your function should look like:
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
view.loadUrl(urlNewString); // you are using siteView here instead of view
return true;
}
Hope this works for you.
Make sure the url starts with http://. Without http it will just show white screen. Because mostly you will copy url and it will start with www.something.com/asdf. That will not work. change it to http://www.something.com/asdf.

Categories

Resources