WebView shouldOverrideUrlLoading() not called for invalid links - android

There are two types of links in the HTML file:
(1) A normal link like http://www.bbb.com/q?type=normal
(2) A short link like /q?type=short.
For the first kind, just load the url. For the second kind, I should prepend it with a fixed address like http://www.abc.com before loading the url.
I am trying to do this with overriding the shouldOverrideUrlLoading() function in WebViewClient. However this function doesn't gets called for the second type of link. I tried prepending the "http://www.abc.com" to the second type of links in the HTML file. Then the function does get called when I click the second kind of link.
I think what's happening is WebView will first check if the link is a valid url. Only if it is valid will the function gets called. Am I right? How can I solve this? Thanks in advance.
contentWebView = new WebView(context);
webViewClient = new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// String not in Logger.
Log.d(TAG, "Here!");
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
context.startActivity(intent);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (hosted) {
contentWebView.setVisibility(VISIBLE);
} else {
summaryTextView.setVisibility(VISIBLE);
articleLinkButton.setVisibility(VISIBLE);
}
progressBar.setVisibility(View.GONE);
}
};
contentWebView.setWebViewClient(webViewClient);
contentWebView.getSettings().setJavaScriptEnabled(true);
contentWebView.loadData(fullString, "text/html", "utf-8");
contentWebView.setVisibility(GONE);
More on this:
I tried changing
contentWebView.loadData(fullString, "text/html", "utf-8");
to
contentWebView.loadDataWithBaseURL("http://www.abc.com", fullString, "text/html", "utf-8", null);
Then the function gets called.
If I change the short link to a full link in the html string manually. Then the function also gets called.
So I think this is probably what is happening: The WebView checks if the link URL is valid. Only when the URL is valid will the shouldOverrideUrlLoading() be called.

You're probably using the KitKat WebView. This is a known issue (I think it's outlined in the migration guide) where URLs that can't be resolved against the base URL are dropped on the floor (you won't get any callbacks for them, neither shouldOverrideUrlLoading nor onPageStarted).
The problem is that your base URL is a data url, so you're trying to resolve '/q?type=short' against 'data:text/html,...' which doesn't make much sense and so the whole attempt to navigate to the URL gets ignored.
This was different for the pre-KK WebView which used KURL instead of GURL for URL processing. GURL is generally more strict (and more secure) than KURL, which is the cause for some incompatibility between the two WebView versions.

Maybe try using onPageStarted method

solution that worked for me was to use loadDataWithBaseURL with an invalid baseUrl and detect that and remove it and replace with "http://" during setWebViewClient
public class MyActivity
extends Activity
{
private static final String badurl = "http://myappname.invalid/";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
...
WebView wv = ((WebView)findViewById(R.id.webview));
WebSettings settings = wv.getSettings();
settings.setJavaScriptEnabled(false);
settings.setSupportMultipleWindows(true);
wv.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
{
handleUrlview.getHitTestResult().getExtra());
return true;
}
});
wv.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
handleUrl(url);
return true;
}
});
wv.loadDataWithBaseURL(badurl,text,"text/html","utf-8",null);
}
private void handleUrl(String url)
{
if (url.startsWith(badurl))
url = "http://"+url.substring(badurl.length());
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} catch (ActivityNotFoundException e) { }
}
}

i faced this problem too and solved it by replacing my html response. In my html response there is no any host in "href" html tags. Then i replaced it following codes and thats working like a charm now :)
String htmlString = AppCache.homePageResponse.showcaase.replace("href=\"/", "href=\"" + "evidea://" );

I found that if your page runs in an iframe, clicking on external (http://www...) links does NOT trigger shouldOverrideUrlLoading() !
See shouldOverrideUrlLoading() not called for external links from iframe

Try this
private static WebView webView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //should be activity_main
webView = (WebView) findViewById(R.id.web);
webView.setWebViewClient(new webviewclient());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://www.yahoo.com");
}
public class webviewclient extends WebViewClient{
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.toString());
return true;
}

Related

How can I Block a Site in WebView

I have to make a webbrowser for android, so I want to try to block a site.
How can I do that?
Lets say your WebView id is myWebView then what you will do is this :
WebView wb = (WebView) findViewById(R.id.myWebView);
wb.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("http://yourBlockedUrl.com")){
//notify the user that this url is blocked
return true;
}
return false;
}
});
by doing this you are overriding the url loading of your webview you can thus block a url from loading.
say you get the url sent as a string "www.google.com", from the edittext just do a check if this is a blocked url.
for example
if( "www.google.com".equalsIgnoreCase(blocked_string))
{
webview.setVisibility(View.GONE);
warning_view.setVisibilty(View.VISIBLE);
}
or you could try overriding the shouldOverrideUrlLoading() in the WebViewClient class
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if(my_url.equals("www.google.com")){
//do something.
}
return true;
}
Creating and setting a WebViewClient subclass. It will be called when things happen that impact the rendering of the content, eg, errors or form submissions. You can also intercept URL loading here (via shouldOverrideUrlLoading()).
public void gotoUrl(View view) {
EditText theEditText = (EditText)findViewById(R.id.urlTxt);
theUrl = theEditText.getText().toString();
//
// String blok= "http://www.teknojurnal.com";
webBrowserKu.loadUrl(theUrl);
}
my web browser when klik go, will process this, so what is the problem? why I cant do the steps from anything for blocking one site?

Android, How to retrieve redirect URL from a WebView?

First i surfed the web but no answer was found matching my case.
I want to grab a specific redirect url from a webview and then keep the webview from opening it. The case is an Instagram redirect url after the user authorized my app. How to do it? Here is my code:
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://api.instagram.com/oauth/authorize/?client_id=my_client_id&redirect_uri=my_redirect_uri&response_type=code");
You will have to set your custom WebviewClient overriding shouldOverrideUrlLoading method for your webview before loading the url.
mWebView.setWebViewClient(new WebViewClient()
{
#SuppressWarnings("deprecation")
#Override
public boolean shouldOverrideUrlLoading(WebView webView, String url)
{
return shouldOverrideUrlLoading(url);
}
#TargetApi(Build.VERSION_CODES.N)
#Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
{
Uri uri = request.getUrl();
return shouldOverrideUrlLoading(uri.toString());
}
private boolean shouldOverrideUrlLoading(final String url)
{
Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
// Here put your code
return true; // Returning True means that application wants to leave the current WebView and handle the url itself, otherwise return false.
}
});
mWebView.loadUrl("Your URL");
Checkout the example code for handling redirect urls and open PDF without download, in webview.
https://gist.github.com/ashishdas09/014a408f9f37504eb2608d98abf49500
You should override shouldOverrideUrlLoading:
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView wView, String url) {
if (url.indexOf('api.instagram.com') > -1) //check if that's a url you want to load internally
{
webView.loadUrl(url);
return true;
}
else
{
return false; //Let the system handle it
}
}
});
Finally thanks to the answer given to my question by Udi I, with a little change, i managed to find a solution to the problem. Here is the code which worked for me:
webView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView wView, String url) {
return (url.indexOf("some part of my redirect uri") > -1);
}
});
webView.loadUrl(myUrl); //myUrl is the initial url.
Using the above code, if there will be any url containing redirect uri, webView won't load it. Else, webView will load it. Also thanks to Kamil Kaminski.
Simply set WebViewClient for your WebView, and override shouldOverrideUrlLoading in WebViewClient. In that method you can grab your url, and decide whether or not your WebView should follow redirection url. Here's example:
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// here you can assign parameter "url" to some field in class
// return true if you want to block redirection, false otherwise
return true;
}
});
You can compare URL strings / particular word, and take actions accordingly -
public boolean shouldOverrideUrlLoading(WebView view, String url) {
super.shouldOverrideUrlLoading(view, url);
if (url.contains(".pdf")
openPDF(url); // handle pdf opening
if(url.startsWith("tel:")
callNumber(url); // handle call processing
...
}
Just to add more, you can prevent webview from showing traditional error message screens, or bypass known errors -
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
if (errorCode == -10) {
System.out.println("Error occured: Error code: "
+ errorCode + "..Ignoring this error");
return;
}
else
{
// Show your custom screen to notify error has occured
}
...
}

Android - Bug in Webview? Some URL's prompt webview to start external browser

I have a "NewsActivity" with a webview. When I start it from my main activity, links are opened in the webview correctly but, for some reason, some url's cause the webview to open but then to immediately launch the external browser. Checking the debug console I have not found any exception or other message thrown by webview as not being able to handle the url.
Please note that I am not talking about a link clicked after the webview has loaded the url/page.
I have also tried to activate javascript in the webview but to no avail.
Also, this happens for just some urls from the same domain (specifically a news website; also, I have no block url or override in place).
Here is one of the urls that fail to open in the webview: url_not_loaded
Here is the code that calls the "NewsActivity"
Intent intent = new Intent(this, NewsActivity.class);
intent.putExtra(MainActivity.EXTRA_MESSAGE, url);
startActivity(intent);
And here is the code in "NewsActivity"
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
Intent intent = getIntent();
String url = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
mWebview = (WebView) findViewById(R.id.newsv);
Log.d(MainActivity.LOG_TAG, "URL: " + url);
mWebview.loadUrl(url);
}
If someone has a clue as to what may be happening or can suggest any idea, I'll be grateful.
Thanks!
Your URL's might have redirects. I encountered a similar problem.
Add this to your activity with the webview.
webView.setWebViewClient(new Callback());
Add this outside of onCreate.
private class Callback extends WebViewClient{ //Helps to open in webview instead of browser
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return (false);
}
}
It's not a bug.
You need to use WebViewClient.
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
System.out.println("hello");
return false;
}
});
//Toast.makeText(this, "", Toast.LENGTH_SHORT);
mWebView.loadUrl(url);
You can set a newWebViewClient like this:
webView.setWebViewClient(new WebViewClient());
But to be more precisely you need to override the shouldOverrideUrlLoading method like this:
webView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
view.loadUrl(url);
return true;
}});

how to track an webpage when it is redirected from another web page within a web view in android

I load "www.gmail.com" in a webview,after login the a new webpage will be loaded i.e. our gmail account page.
I have to track that url when I submit login details and the new webpage is loading,I don't need any hard coded value to redirect to any webpage,I want to get that url when a webpage is loaded from another webpage,how can I achieve this.Please help me.
This is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
title_text=(TextView)findViewById(R.id.urltxt);
showWeb=(WebView)findViewById(R.id.webview_details_body);
showWeb.setWebViewClient(new HelloWeb());
showWeb.getSettings().setBuiltInZoomControls(true);
showWeb.getSettings().setLoadWithOverviewMode(true);//show the webpage in fullsize with all info
showWeb.getSettings().setUseWideViewPort(true);
WebSettings webSettings = showWeb.getSettings();
webSettings.setJavaScriptEnabled(true);
showWebClick();
}
private void showWebClick() {
showWeb.loadUrl("http://www.gmail.com/");
}
public boolean onKeyDown(int keyCode,KeyEvent event){
if((keyCode==KeyEvent.ACTION_DOWN)&&showWeb.canGoBack()){
showWeb.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
public class HelloWeb extends WebViewClient{
#Override
public boolean shouldOverrideUrlLoading(WebView vw,String url){
vw.loadUrl(url);
s=vw.getUrl();
title_text.setText( s);
return super.shouldOverrideUrlLoading(vw, url);
}
}
}
You can achieve this using method getUrl() of webview client.
But, This is not always the same as the URL passed to WebViewClient.onPageStarted because although the load for that URL has begun, the current page may not have changed.
You can refer below link :
http://developer.android.com/reference/android/webkit/WebView.html#getUrl%28%29
So you have to call geturl method on onPageFinished method. It will be good.
#Override
public void onPageFinished(WebView view, String url) {
/*do your stuff here.*/
}
Your webview will most likely call either shouldOverrideUrlLoading or onLoadResource in its webviewclient with an url of its redirect.
If I understand your question correct, try overriding onLoadResource in your WebViewClient and look at the url parameter.
Using onLoadResource will also generate urls for other resources as well, such as images.

Android WebView, how to handle redirects in app instead of opening a browser

So right now in my app the URL I'm accessing has a redirect, and when this happens the WebView will open a new browser, instead of staying in my app. Is there a way I can change the settings so the View will redirect to the URL like normal, but stay in my app instead of opening a new browser?
Edit:
I want the redirecting URL, I just don't know how to create it, so the only way to get to that URL is through one that will cause a redirect to the one I want.
For example: When you go here: http://www.amazon.com/gp/aw/s/ref=is_box_/k=9780735622777 notice how it will redirect the URL to the actual product. In my app, if I open it in a new browser, it will do that just fine, however if I keep it in my app with a WebView, it will show up as though it's doing a search for k=9780735622777, like this: http://www.amazon.com/gp/aw/s/ref=is_s_?k=k%3D9780735622777&x=0&y=0 . OR, it will open the view in the browser and show what is appropriate. However, I want to keep everything in my app.
Create a WebViewClient, and override the shouldOverrideUrlLoading method.
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url){
// do your handling codes here, which url is the requested url
// probably you need to open that url rather than redirect:
view.loadUrl(url);
return false; // then it is not handled by default action
}
});
According to the official documentation, a click on any link in WebView launches an application that handles URLs, which by default is a browser. You need to override the default behavior like this
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
Just adding a default custom WebViewClient will do. This makes the WebView handle any loaded urls itself.
mWebView.setWebViewClient(new WebViewClient());
You will have to set your custom WebviewClient overriding shouldOverrideUrlLoading method for your webview before loading the url.
mWebView.setWebViewClient(new WebViewClient()
{
#SuppressWarnings("deprecation")
#Override
public boolean shouldOverrideUrlLoading(WebView webView, String url)
{
return shouldOverrideUrlLoading(url);
}
#TargetApi(Build.VERSION_CODES.N)
#Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
{
Uri uri = request.getUrl();
return shouldOverrideUrlLoading(uri.toString());
}
private boolean shouldOverrideUrlLoading(final String url)
{
Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
// Here put your code
return true; // Returning True means that application wants to leave the current WebView and handle the url itself, otherwise return false.
}
});
Checkout the example code for handling redirect urls and open PDF without download, in webview.
https://gist.github.com/ashishdas09/014a408f9f37504eb2608d98abf49500
Create a class that implements webviewclient and add the following code that allows ovveriding the url string as shown below.
You can see these [example][1]
public class myWebClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
On your constructor, create a webview object as shown below.
web = new WebView(this); web.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
Then add the following code to perform loading of urls inside your app
WebSettings settings=web.getSettings();
settings.setJavaScriptEnabled(true);
web.loadUrl("http://www.facebook.com");
web.setWebViewClient(new myWebClient());
web.setWebChromeClient(new WebChromeClient() {
//
//
}
Please use the below kotlin code
webview.setWebViewClient(object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return false
}
})
For more info click here
In Kotlin, to navigate within same webView we needed to override the shouldOverrideUrlLoading for webview
If return type is true then navigation will be blocked If return
type is false then navigation will happen
object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
return true
}
}.also { webView.webViewClient = it }
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (url.equals("your url")) {
Intent intent = new Intent(view.getContext(), TransferAllDoneActivity.class);
startActivity(intent);
}
}

Categories

Resources