Show ProgressBar while loading a url to a WebView - android

Is it possible to show a progressbar while loading a url? I need to show the level of progress in the progressbar for which i can use a custom progressbar. But am not able to find out the code for getting he exact progress of how much the url has loaded. This is my current code:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
browser = (WebView)findViewById(R.id.webView1);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
browser.setWebViewClient(new MyBrowser());
browser.setWebChromeClient(new MyCustomChromeClient());
mContext=this.getApplicationContext();
browser.loadUrl(target_url);
MainActivity.this.progressBar.setProgress(0);
}
private class MyBrowser extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String host = Uri.parse(url).getHost();
if (host.equals(target_url_prefix))
{
if(mWebviewPop!=null)
{
mWebviewPop.setVisibility(View.GONE);
baseLayout.removeView(mWebviewPop);
mWebviewPop=null;
}
return false;
}
if(host.equals("m.facebook.com"))
{
return false;
}
view.loadUrl(url);
return true;
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
noInternet();
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
visible();
}
#Override
public void onPageFinished(WebView view, String url) {
unvisible();
System.out.println("\n" +view.getUrl());
if(url.startsWith("https://m.facebook.com/v2.1/dialog/oauth")){
if(mWebviewPop!=null)
{
mWebviewPop.setVisibility(View.GONE);
baseLayout.removeView(mWebviewPop);
mWebviewPop=null;
}
view.loadUrl(redirectUrl);
return;
}
super.onPageFinished(view, url);
}
}
private class MyCustomChromeClient extends WebChromeClient
{
#Override
public boolean onCreateWindow(WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg) {
mWebviewPop = new WebView(mContext);
mWebviewPop.setVerticalScrollBarEnabled(false);
mWebviewPop.setHorizontalScrollBarEnabled(false);
mWebviewPop.setWebViewClient(new MyBrowser());
mWebviewPop.getSettings().setJavaScriptEnabled(true);
mWebviewPop.getSettings().setSavePassword(false);
mWebviewPop.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
baseLayout.addView(mWebviewPop);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(mWebviewPop);
resultMsg.sendToTarget();
return true;
}
#Override
public void onCloseWindow(WebView window) {
}
#Override
public void onProgressChanged(WebView view, int newProgress) {
MainActivity.this.setValue(newProgress);
super.onProgressChanged(view, newProgress);
}
}
public void setValue(int progress) {
this.progressBar.setProgress(progress);
}
}
How to get the exact progress of loading a url. With this code, i can get the progressbar loading, but its shown as an indeterminate progressbar. I want to show a progressbar which is a customised view. It should display the percentage of succesful loading of the url. So maye i can inflate a customised view, but again i dont know how to get exact percentage. Can someone help me with this code.

The onProgressChanged() of WebChromeClient gives you the progress about the status of page loading. See the below info about the function from the android api docs.
public void onProgressChanged (WebView view, int newProgress)
Added in API level 1
Tell the host application the current progress of loading a page.
Parameters
view The WebView that initiated the callback.
newProgress Current page loading progress, represented by an integer between 0 and 100.

I am not familiar with your Webview. But I open URLs in doInBackground AsyncTask ussualy. So I cannot find a way to express this in percentage directly. But what you could do is maybe trick around, with something like:
Set 20% when your app has confirmed that there is a INTERNET connection enables on the Device.
Set 50% when it reaches the AsyncTask to open URL (or however you initialize .connect())
And finally set 100% when URL is opened.
This is a dummy method. But otherwise you should somehow work with Time (seconds). But an App cannot forsee how long will it need to open the URL. The 100% would represent seconds needed to open the URL, but this is not accessable during loading the URL, since App doesn't know at that time how much it needs to open it.
You could do a test run and time the seconds. Set a timer, when you start opening the URL, and stop the timer when it opens it. But that time would just be in that particular case.. if someone uses a slow Android Device, or Bad Internet Connection, it would probably take longer.
Hope my answer is alteast a bit helpful. If there exists a method to do something more precisely, I am sure guys here will write it.

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
}
}
});

How to make a WebView visible only after it finished displaying content?

I have a webView, where I display a HTML I fetch from the backend.My problem is that I am trying to display a loading message, and show the content only after the page is done.
For doing that, I tried to use onPageFinished, which winda works, but not entirely, because it is called after the data is fetched, but BEFORE the page is displayed, so I'm still displaying a blank screen for about 1 second, before finally displaying the HTML.
From the oficial docs:
public void onPageFinished (WebView view, String url)
Added in API level 1
Notify the host application that a page has finished loading. This method is called only for main frame. When onPageFinished() is called, the rendering picture may not be updated yet. To get the notification for the new Picture, use onNewPicture(WebView, Picture).
The problem is that onNewPicture(WebView, Picture) is deprecated
So my question is, is there a way to know when the page is finished, but also fully displayed?
Here is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.messageId = this.getIntent().getStringExtra(ITEM_ID_KEY);
this.setUpActionBar();
this.setContentView(R.layout.activity_inbox_item_detail);
WebView view = (WebView) this.findViewById(R.id.webview);
view.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
view.setVisibility(View.VISIBLE);
}
});
this.fetchInboxDetailsTask(this.messageId);
}
I have a WebView in a fragment and, just for your reference, I have set it up like this.
May be you are missing something. "onPageFinished" works just fine for me.
In onViewCreated method:
mWebView = (WebView) view.findViewById(R.id.appWebView);
mWebView.setWebViewClient(new WebViewClient()
{
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
// Handle the error
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url)
{
webViewProgressBar.setVisibility(View.GONE);
super.onPageFinished(view, url);
}
});
and then:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.loadUrl("http://play.google.com/store/apps/");
You may consider using the Advanced Webview Library for android it provides an interface to reaspond to when page start loading and when finishes! here (AdvancedWebView)

Slower page loading while invoking WebViewClient for the firsttime

Below is my code for WebViewClient. I have invoked the class by clicking a button.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.webview);
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
activity.setTitle("Loading...");
activity.setProgress(progress * 100);
if (progress == 100)
activity.setTitle(R.string.app_name);
}
});
webView.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// Handle the error
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webView.loadUrl("http://mylink.com");
// String customHtml =
// "<html><body><h1>Hello, WebView</h1></body></html>";
// webView.loadData(customHtml, "text/html", "UTF-8");
}
}
Its taking more time to load the WebViewClient. I need to speed it up. Any suggestions
Nothing wrong with your code as far as I can see. I would strongly suggest you check out the performance of the web server you are connecting to as this will most likely be the cause of your problems. Particularly look at the servers response times. To test the performance of your web view try setting the url to a fast responding web site, something like google.com.
I think WebView creates a database for all sorts of reasons (like web cache) in your app's temp dir.
This DB is created the first time you call WebView from the app. In subsequent calls it is re-used.
Therefore it is possible that this creation process is what you're experiencing.

WebView.getUrl() returns null

I have an issue with Webview. I'm programming my own WebChromeClient class overriding onProgressChanged method because I want to show the page when it finishes loading and then, to hide the splash screen. As I just want it to happen with a specific URL, I compare the actual WebView URL with a specific string, but there is a problem, I get a null pointer when webview.getUrl() method is called and my application finishes.
This is the code:
private class MyWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged (WebView webview, int newProgress) {
super.onProgressChanged(webview,newProgress);
if(webview.equals(w1) && newProgress == 100 && webview.getUrl().startsWith("https://ssl.facebook.com/login.php")) {
webview.setVisibility(WebView.VISIBLE);
ImageView imageview = (ImageView)findViewById(R.id.ivsplash);
imageview.setVisibility(ImageView.GONE);
ProgressBar progressbar = (ProgressBar)findViewById(R.id.pbsplash);
progressbar.setVisibility(ProgressBar.GONE);
}
}
}
I do this for avoid the webview takes three or four seconds to render the page, but it doesn't work. The code I used before was:
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url) {
super.shouldOverrideUrlLoading(webview, url);
webview.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView webview, String url) {
if(url.startsWith("https://ssl.facebook.com/login.php")) {
webview.setVisibility(WebView.VISIBLE);
ImageView imageview = (ImageView)findViewById(R.id.ivsplash);
imageview.setVisibility(ImageView.GONE);
ProgressBar progressbar = (ProgressBar)findViewById(R.id.pbsplash);
progressbar.setVisibility(ProgressBar.GONE);
}
}
}
Not sure if this is possible with WebChromeClient, but I was able to do this using
WebViewClient and overloading onLoadResource, onReceivedError and onPageFinished
This is what I've done
onLoadResource
mwebview.setVisibility(View.GONE);
onReceivedError
mwebview.setVisibility(View.VISIBLE);
onPageFinished
mwebview.setVisibility(View.VISIBLE);
and intially in XML the webview is set as GONE
android:visibility="gone"
I too use it for Facebook and works fine.

Categories

Resources