Android WebBrowser using WebView

Based on the info in my previous article I’d like to present the steps to create a simple Android Internet Browser application, with a header, a WebView central area and a footer – all dynamical, without using XMLs:

Some details:

  • In AndroidManifest.xml, you will need to include the INTERNET permissions:
  • The interface: you can learn how to use the nice RelativeLayout control and create the interface, as per my previous article on this topic. The user controls are the top address field and the GO button, the BACK, FORWARD, RELOAD and STOP at the bottom.
  • The WebView control: will handle all the HTML rendering and other complex function related to internet browsers. The webview is created between the Header and the Footer, and the content is finger-friendly (finger scrollable). By default the zoom level has been configured to fit the pages in the screen’s width.
  • For the WebView control I’ve enabled JavaScript support and added a WebViewClient class to intercept the various events like page loading events (start/ready):
  • m_web.getSettings().setJavaScriptEnabled(true);
    m_web.setWebViewClient(new MyWebViewClient());
    

    Note: The WebView Client class is quite simple:

    private class MyWebViewClient extends WebViewClient {
    @Override  
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
    	Log.d(LOG_TAG, "onPageStarted");
    	m_tv.setText("Loading page...");
    	//stop button is enabled only when pages are loading
    	m_bButStop.setEnabled(true); 
    }
    @Override  
    public void onPageFinished(WebView view, String url) {
    	Log.d(LOG_TAG, "onPageFinished");
    	m_tv.setText("Ready ");
    	//stop button is disabled when pages are already loaded
    	m_bButStop.setEnabled(false);
    	// This call inject JavaScript into the page which just finished loading.   
    	m_web.loadUrl("javascript:window.HTMLOUT.showHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');");
    	// adjust prev/next buttons, only if history is available
    	m_bButBack.setEnabled(m_web.canGoBack()); 
    	m_bButFwd.setEnabled(m_web.canGoForward());
    }
    
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    	view.loadUrl(url);
    	return true;
    }
    
    }
    

    Details:

  • When the page starts loading (onPageStarted) we set the proper content in the status textview, and we enable the STOP button. This button is enabled when a page is loading, and is disabled when the page is completely loaded, because it doesn’t make sense to stop something that has already finished loading, does it?
  • When the page is loaded (onPageFinished) we show “Ready” in the status textview, we disable the STOP button, and we inject a JavaScript so we would have access to the HTML code of the page we’ve loaded.
    To run the Javascript we need to call :
  • // set java script used to get the HTML code
    m_web.addJavascriptInterface(new JavaScriptInterface(), "HTMLOUT");
    
  • Where the JavaScriptInterface is a simple HTML reader based on the “showHTML” function (that we call after a page is loaded):
  • // Used with Webview, to get the HTML code
    class JavaScriptInterface{
    public void showHTML(String html) {
    	m_nHTMLSize = 0;
    	if (html !=null) {
    		//int i = html.lastIndexOf(""); //search for something in the text
    		m_nHTMLSize = html.length();
    		Log.d(LOG_TAG, "HTML content is: "+html+"\nSize:"+m_nHTMLSize+" bytes");
    		
    	}
    }
    }
    
  • The Third of the page-related events, is shouldOverrideUrlLoading:
  • @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    	view.loadUrl(url);
    	return true;
    }
    
  • This is a very important piece of code, we use this to allow our Android Internet Browser to follow newly pressed links and handle them inside our own Browser.
  • For further details, see the code, it is easy and self explanatory:
    Android Internet Browser Webview Sample

    This article has 11 Comments

    1. I tried this code and it works great. However, if I load a page that contains text input boxes, when I tap the input the web view flashes black for a second (actually it is flashing transparent, because if I set the background color for the layout underneath the WebView, that is the color I see. And sometimes it doesn’t even redraw except for the input that has focus.

      Every other WebView code I can find has this same problem — does anyone know how to fix it?
      –Thanks

    2. Please don’t call loadUrl from shouldOverrideUrlLoading. shouldOverrideUrlLoading is called for subframes with non-https schemes. If you go to a a page like http://jsbin.com/gupug/1/quiet your code will end up calling view.loadUrl(‘tel:1234’) and you will end up showing an error page, since the webview doesn’t know how to load a tel: URL.

      The right thing to do is to return false from shouldOverrideUrlLoading.

    Leave a Reply