Thursday, March 27, 2014

Overiding a URL click in android WebView

If you have used the android WebView, you are quite familiar that the if you click on a url on a web page, the link is opened in the default web browser of the device. But this can be easily overridden using the bellow code.

WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    webView = (WebView) findViewById(R.id.webViewPage);
    ........
    webView.setWebViewClient(new WebViewClient() {
        @SuppressLint("NewApi")
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            //page loading logic here
            return true;
        }
    });
}

If you are using the android API prior to API 3, you could have done it easily using 
webview.loadUrl(url);

But if you are using an API level 3 or a later version (which will be the case in the most of the times), loading the url will be bit trickier. To make the application more interactive, it is mandatory to use a separate thread to load the page. If it is done in the same thread which is used to handle user interactions, user interface may not respond to the user. So it cannot be easily done using the loadUrl method. There are several method to do this. First and the worst way of doing it is using a method called StrictMode.

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

If you add this to the onCreate method you will not face problems when running the app. But I guarantee that the application wont be very interactive depending on the internet connection you are having.

To properly do this you will have to use a AsyncTask. AsyncTask create a separate thread which can be used for data loading without making the application not interactive. Below here explains how to create a AsyncTask.

//Create a separate thread to load the web page
private class LoadPageTask extends AsyncTask<String, HtmlPage, HtmlPage> {
    protected HtmlPage doInBackground(String... urls) {
        //page loading logic here.
    }

    protected void onPostExecute(HtmlPage page) {

        //things to do after completing the task defined in doInBackground method.
    }

    @Override

    protected void onPreExecute() {
        //things to do prior to the task defined in doInBackground method.
    }
}

You can use different methods to load the page to the WebView. In my case I used the HttpPost method to get the input stream of the web page and and then parse it using a HTML parser and loading the page to the WebView using the same HTML parser.