Android Webview: Disable confirm navigation - android

Is it possible to disable a confirm navigation pop up in android webview from a website that I am viewing?
I tried this one and I what I did is just return 'true' without showing any pop-up, but the navigation pop up still shows up. I want to disable it and I would like to just automatically navigate without any warning.
Here's the CustomWebChromeClient for my webview
public class CustomWebChromeClient extends WebChromeClient {
#Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return true;
}
}

You can override onJsBeforeUnload to always return true.
onJsBeforeUnload is the callback that gets invoked before the confirm navigation dialog pops up.
https://developer.android.com/reference/android/webkit/WebChromeClient.html#onJsBeforeUnload(android.webkit.WebView, java.lang.String, java.lang.String, android.webkit.JsResult)
Edit: As mentioned by AndyW, confirm or cancel methods should be invoked on jsResult argument otherwise the app might freeze because of the pending javascript dialog.

For me overriding onJsConfirm as followed did it:
#Override
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}

Why don't you create a webView in xml and use that webview in activity instead of using a class with webChromeClient, the below steps may help you.
step 1:
Create a webview in your xml file and call this view in Java
webView = (WebView) findViewById(R.id.exampleWebView);
step 2:
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
step 3:
webView.loadUrl(getResources().getString(R.string.olo_non_loggedin_url));
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
super.onPageStarted(view, url, favicon);
pBar.setVisibility(View.VISIBLE);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
pBar.setVisibility(View.GONE);
}
});

Related

Webview Loads some internal URLs and hence My "Please Wait" Loader fluctuates

I have one WebView in my android App which i use to log into my App.
The URL which I load in WebView is "https://accounts.google.com/ServiceLogin#identifier" with ru to my website.
Before loading I start a progress dialog which says "Please wait".
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Utils.mShowProgrossDiolog(mContext);
}
#Override
public void onPageFinished(WebView view, String inComingURL) {
super.onPageFinished(view, inComingURL);
Utils.mHideProgrossDiolog();
}
Problem is since WebView loads some internal URLs to verify and other things...My Loader fluctuates as show-hide-show-hide.
I want it to hide only when final site is loaded. Can someone help me what to do in this case.
You can check the loaded URL using vwebView.getUrl(); in
public void onPageFinished(WebView view, String inComingURL) and only if it matches the URL you want to load dismiss the progress dialog. You might have to handle cases like when the url doesnt load at all.
You can check the progress of page loading by web chrome client and once it reach to 100% you can hide your dialog.
private class MyWebChromeClient extends WebChromeClient{
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if(newProgress==100){
progressDialog.dismiss();
}
}
}
You have to set webview client for your web view to get callback.
webView.setWebChromeClient(new MyWebChromeClient());

Android: How to check for successful load of url when using webview.loadUrl

In webview android I am trying to load a url and in order to check if the load of this url is done successfully (internet connection was available, the server was up etc) I was under the impression that webview.loadUrl would throw exceptions, but wrong! as it explicitly is stated in here "an exception will NOT be thrown".
So how can I check to see if webview.loadUrl did not fail ?
Unfortunately, currently there is no easy way in WebView to ensure that everything on the page has been loaded successfully. We are hoping for a better API to come up in future version. Let me explain what you can do now.
First of all, in order to detect any problems that prevent WebView from making a connection to the server for loading your main page (e.g. bad domain name, I/O error, etc.), you should use WebViewClient.onReceivedError callback as other people correctly suggest:
public class MyWebViewClient extends WebViewClient {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Make a note about the failed load.
}
}
myWebView.setWebViewClient(new MyWebViewClient());
If the server connection was successful, and the main page was retrieved and parsed, you will receive WebView.onPageFinished callback, so you also need to have this in your WebViewClient subclass:
public class MyWebViewClient extends WebViewClient {
...
#Override
public void onPageFinished(WebView view, String url) {
// Make a note that the page has finished loading.
}
...
}
The caveat here is that if you have received an HTTP error from the server (e.g. a 404 or a 500 error), this callback will be called anyway, it's just the content that you will get in your WebView will be a server error page. People suggest different ways of how to deal with it, see the answers here: How can I check from Android WebView if a page is a "404 page not found"? Basically, it really depends on what you expect to be a "good" page and a "error" page. Unfortunately, there is currently no way for the app to get the HTTP response code from WebView.
The callbacks WebViewClient.onPageStarted and WebViewClient.onProgressChanged are only useful if you want to draw a progress bar as you are loading the page.
Also note that the way of overriding WebViewClient.shouldOverrideUrlLoading that people usually suggest is not correct:
public class MyWebViewClient extends WebViewClient {
...
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// !!! DO NOT DO THIS UNCONDITIONALLY !!!
view.loadUrl(url);
return true;
}
...
}
What few developers realize is that the callback is also called for subframes with non-https schemes. If you'll encounter something like <iframe src='tel:1234'>, you will end up executing view.loadUrl('tel:1234') and your app will show an error page, since WebView doesn't know how to load a tel: URL.
It is recommended to simply return false from the method, if you want WebView to do the loading:
public class MyWebViewClient extends WebViewClient {
...
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Returning 'false' unconditionally is fine.
return false;
}
...
}
This doesn’t mean you should not call WebView.loadUrl from shouldOverrideUrlLoading at all. The specific pattern to avoid is doing so unconditionally for all URLs.
public class AppWebViewClient extends WebViewClient {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
setProgressBar(true);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
//Page load finished
super.onPageFinished(view, url);
setProgressBar(false);
}
}
and then you can do
webView.setWebViewClient(new AppWebViewClient());
For the error part you can override the onReceivedError method
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
}
Here is what I came up with, it works like a charm.
Boolean failedLoading = false;
WebView webView = view.findViewById(R.id.webView);
webView.loadUrl("www.example.com");
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!failedLoading) {
webView.setVisibility(View.VISIBLE);
webView.setAlpha(0f);
ObjectAnimator anim = ObjectAnimator.ofFloat(webView, "alpha",1f);
anim.setDuration(500);
anim.start();
}
}
#Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
failedLoading = true;
}
});
It will also work great if you add some kind of a refresh button and then you can call the code above inside a function to try again.
You can check if a URL is loaded successfully by using onProgressChanged()
mWebView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
if (progress == 100) {
//your url is loaded successfully
}
}
});

Webview - onPageFinished is not called

In my App i want to cache a webapage in the background with a hidden webview (at the same time another webview is visible to the user and loads another url).
I start the caching in onResume. Here are the code snippets:
1.) onResume:
#Override
public void onResume() {
new LibraryCacher().startCaching(this);
//some more code...
}
2.) LibraryCacher:
public class LibraryCacher extends BasicClass {
public LibraryCacher () {}
public void startCaching(Context context) {
getLogger().debug("startCaching()");
if (NetworkHandler.isOnline(context) == false) {
getLogger().info("We are offline, no caching");
return;
}
final String URL_TO_CACHE = "http://myUrl.com";
WebView w = new WebView(context);
w.setVisibility(View.GONE);
WebSettings webset = w.getSettings();
webset.setJavaScriptEnabled(true);
webset.setDomStorageEnabled(true);
webset.setDatabaseEnabled(true);
webset.setJavaScriptCanOpenWindowsAutomatically(true);
webset.setSupportMultipleWindows(true);
webset.setAppCacheEnabled(true);
webset.setLoadsImagesAutomatically(true);
webset.setAppCachePath(w.getContext().getCacheDir().getAbsolutePath());
webset.setAllowFileAccess(true);
webset.setCacheMode(WebSettings.LOAD_DEFAULT);
w.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
getLogger().debug(url + " caching...");
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
getLogger().debug(url + "cached");
}
});
w.setWebChromeClient(new WebChromeClient());
getLogger().debug("load Url");
w.loadUrl(URL_TO_CACHE);
}
}
At the FIRST-CACHE-TRY (app starts the first time) logcat looks like this:
startCaching()
load Url
http://myUrl.com caching...
After that i put the app in the background and resume it. So, at the SECOND-CACHE-TRY logcat looks like this:
startCaching()
loadUrl
http://myUrl.com caching...
http://myUrl.com cached
My question:
Why doesn't the webview invoke its method onPageFinished at the first try?
EDIT :
It works, if i invoke
new LibraryCacher().startCaching(this);
in onPageFinished of the other webview, which is visible to the user and loads simultaneously another url.
Does anyone know why?
Webviews in android seem to have some shared state. In my case, onPageFinished was never called, because i used:
#Override
public void onPause() {
webView.pauseTimers();
}
On a completely different webview, in a different activity.

Android detect webview URL change

I have a webview in my android app and would like to detect when the url changes.
I want to use this to hide the info button in the top bar when the user is on the info.php page and show it again when he is not on the info.php page.
I googled but can't find any working code, can anybody help me?
I know I'm late to the game but I ran into this issue over and over ... I finally found a sloution which is pretty straight forward. Just override WebViewClient.doUpdateVisitedHistory
override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
// your code here
super.doUpdateVisitedHistory(view, url, isReload)
}
It works with all url changes even the javascript ones!
If this does not make you happy then I don't know what will :)
You can use WebViewClient.shouldOverrideUrlLoading to detect every URL changes on your WebViewClient
For those load url by javascript. There is a way to detect the url change by JavascriptInterface. Here I use youtube for example. Use JavaScriptInteface has async issue, luckily its just a callback here so that would be less issue. Notice that #javascriptinterface annotation must be existed.
{
youtubeView.getSettings().setJavaScriptEnabled(true);
youtubeView.setWebViewClient(mWebViewClient);
youtubeView.addJavascriptInterface(new MyJavaScriptInterface(),
"android");
youtubeView.loadUrl("http://www.youtube.com");
}
WebViewClient mWebViewClient = new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:window.android.onUrlChange(window.location.href);");
};
};
class MyJavaScriptInterface {
#JavascriptInterface
public void onUrlChange(String url) {
Log.d("hydrated", "onUrlChange" + url);
}
}
if you override this method of WebViewClient you will be able to handle url changes, and javascript url changes:
public class YXWebViewClient extends WebViewClient {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.i("Listener", "Start");
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.i("Listener", "Finish");
}
}
and then in your WebView set the WebViewClient
yxWebViewClient = new YXWebViewClient();
webview.setWebViewClient(yxWebViewClient);
I used this method:
webView.setWebChromeClient(new WebChromeClient()
{
#Override public void onProgressChanged(WebView view, int newProgress) {
if (view.getUrl().equals(mUrl))
{
}
else
{
mUrl = view.getUrl();
// onUrlChanged(mUrl) // url changed
}
super.onProgressChanged(view, newProgress);
}
};
);
mUrl is a fields as String...
Try to use onLoadResource. It will be called at least 1 time even if you are using
JS to change your url. But it may be called more than one time, so be careful.
Method onPageFinished seems to work at least in modern WebViews.
An implementation of rinkal-bhanderi's answer would look like this:
class MyWebClient(
private val myCustomMethod: () -> Unit) : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?,
url: String?): Boolean {
myCustomMethod()
return true
}
}
}
And you would use it like:
webview.webViewClient = MyWebClient(::hideButton)
Where webview is the actual webview you get from calling FindViewById or the object reference you get from binding. And hideButton is a method accessible in the same scope last expression is evaluated.
I had an interesting problem that brought me to this question and happy to provide a solution that may help someone else if they come this way due to a googlebingyahoo search.
mwebVew.reload() would not pick up the new URL I wanted to load once I returned from a preference screen where I either logged on the user or logged off the user. It would update the shared preferences well enough but not update and replace the url web page. So after a few hours of not seeing an answer I tried the following and it worked a real treat.
mWebView.resumeTimers();
Here is the link to the doco if you want more info.
Hope it saves someone else the pain I went through, and happy to have someone tell me I should of implemented it another way.
I had the same problem. So i've solved this problem by overriding public void onPageStarted(WebView view, String url, Bitmap favicon) method as follows:
webView.setWebViewClient(new WebViewClient(){
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
// Here you can check your new URL.
Log.e("URL", url);
super.onPageStarted(view, url, favicon);
}
});
Also you can overridepublic void onPageFinished(WebView view, String url) method to get a new URL at the end of page load process.
My requirement was to handle the visibility of a floating button in my page based on the url change.
if url is changing from https/ooooo//login to https/ooooo//homepage
it may not be registered in onPageFinished or shouldOverrideUrlLoading.
This was the issue I was facing.
I fixed that issue by following method:
#Override
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
super.doUpdateVisitedHistory(view, url, isReload);
String currentUrl = view.getUrl();
}
*please don't use url which we are getting with doUpdateVisitedHistory method.That will be the basic url.so go with view.getUrl().
:)
Use WebViewClient.shouldOverrideUrlLoading() when the base/host url changes. Use Use WebViewClient.doUpdateVisitedHistory() method of webview if the base url doesnt change like it happens in single page applications and it detects URL change by javascript which does not lead to a web page reload. #Helin Wang
This will help to detect redirect caused by javascript.
WebViewClient mWebViewClient = new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:window.android.onUrlChange(window.location.href);"); }
};
myWebView.setWebViewClient(mWebViewClient);
}
#JavascriptInterface
public void onUrlChange(String url) {
Toast.makeText(mContext, "Url redirected",Toast.LENGTH_SHORT).show();
}

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