Search This Blog

Thursday, July 19, 2012

Web View in Android

Webview is a view that displays webpages from online or load active web content within your activity.
It is important to add the following permission into manifest for your Activity to access the Internet and load web pages in a WebView, you must add the INTERNET permissions to your Android Manifest file:
 
<uses-permission android:name="android.permission.INTERNET" />
In this blog I am going to share my experience on Webview with a sample example.

By default, a WebView provides no browser-like widgets, does not enable JavaScript and web page errors are ignored. If your goal is only to display some HTML as a part of your UI, this is probably fine; the user won't need to interact with the web page beyond reading it, and the web page won't need to interact with the user. If you actually want a full-blown web browser, then you probably want to invoke the Browser application with a URL Intent rather than show it with a WebView. These can be achieved by adding below line to your activity's onCreate() method


protected WebView browser;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
       setContentView(R.layout.webapp);

       browser = (WebView) findViewById(R.id.webview);
       browser.loadUrl("http://www.google.com"); 
    }
To achieve these we also required to define WebView properties in webapp.xml

<?xml version="1.0" encoding="utf-8"?>
<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
In the above file I am not specifying any layout since I am going to handle only WebView.
Now If we compile and run this app it displays Google page in browser window. After running this application if you take a look on task manager you can see that our default browser is also running alongside with our app, so in order to make the page to be displayed within our activity we need extend WebViewClient as given below
browser.setWebViewClient(new WebClient());
Now we need to extend WebViewClient

public class WebClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // TODO Auto-generated method stub
            view.loadUrl(url);
            return true;
        }
    }
After adding the above mentioned line if you try to run the application you can't able to view the webpage. This is due to WebView does not enable JavaScript by default ,so page errors are ignored so we need to add the settings to enable java script for our WebView as shown below
browser.getSettings().setJavaScriptEnabled(true); 
No you can see the page loading properly.

The next phase involves handling orientation in WebView, These condition can be identified when you try to rotate the screen your activity gets destroyed and recreated and so your page will be reloaded, In order to avoid this situation we need to save the state of our WebView and need to override onConfigurationChanged method as shown below

// To save the current WebView state we need to override this method
@Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        browser.saveState(outState);
        super.onSaveInstanceState(outState);
    }
@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        browser.restoreState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }
@Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);
    }
 The purpose of onConfigurationChange method is, it will inform android OS that the orientation will be handled manually and we need to add the following lines under Androidmanifest.xml file
<activity android:name="WebViewTest"
    android:label="@string/app_name"
    android:configChanges="keyboardHidden|orientation">
     </activity>
 After adding this you can run your application in target device and orientation will work properly and also page won't get reloaded, but if your target device is of Android ICS then we need to add two more options in order to make orientation to work properly

android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"
The below are the options which can be added as value for configChanges tag

android:configChanges=["mcc", "mnc", "locale",
                                 "touchscreen", "keyboard", "keyboardHidden",
                                 "navigation", "screenLayout", "fontScale", "uiMode",
                                 "orientation", "screenSize", "smallestScreenSize"]
The full details for this command are found at the link  ConfigChanges

The final phase is to decorate your activity by showing progress bar adding zoom control options etc. which are discussed below,
There are two types of progress feature are available to added as window component for an activity, Feature Progress, Feature Indeterminate Progress. Feature Progress displays like a normal progress bar with variable bounds whereas Indeterminate Progress works for the case which has no bounds to stop unless until the task has been completed.
Here we are going to add both types of progress bar to window activity, So to do that add the below lines before setting content view to your activity.

this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.webapp);
Now to make the progress visible in activity we need to add the below line,

getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
                Window.PROGRESS_VISIBILITY_ON);
setProgressBarIndeterminateVisibility(true); 
To handle progress bar bound limit we need to extend WebChromeClient  as described below

browser.setWebChromeClient(new ChromeClient());
public class ChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            // TODO Auto-generated method stub
            activity.setTitle(browser.getUrl());
            activity.setProgress(newProgress * 100);
            if (newProgress == 100)
                activity.setTitle(R.string.app_name);
        }
    }
Now if you run the app the progress bar will display with the name of URL inside the progress bar and showing indeterminate progress to the right side of the activity window.

The Zoom controls can be added by using below line

browser.getSettings().setBuiltInZoomControls(true);
In order to complete our application we can add a condition that our application needs to open if network connection is present. To check that add below lines before loading your desired URL.


  if (hasInternet(getApplicationContext())) {
                browser.loadUrl("Load URL String");
            } else {
                setProgressBarIndeterminateVisibility(false);
                //Show Alert Messages
            }

        public boolean hasInternet(Context con) {
            NetworkInfo info = (NetworkInfo) ((ConnectivityManager) con
                    .getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
            if (info == null || !info.isConnected())
                return false;
            return true;
        } 
                     
 The above method will check the status of network connectivity so we need to add permission to access network state

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
All type of built-in Android permissions can be found at the link Android Permissions

So now we can handle some basic operations on WebView with concepts defined.