Software Development

Pro tip: Include a clickable phone number in Android's web view

Here's a quick device-agnostic trick for intercepting a link inside Android's web view.

android-040714.jpg

I've been working with web views at the behest of a client. To a native app developer, web views can be particularly challenging. One such challenge I recently conquered was including a clickable phone number in the web view.

The client's request was more than reasonable. The web page would display a phone number. When the user clicked the phone number, the app would launch the dialer pre-populated with the phone number from the website.

According to everything I read, this should "just work" in a mobile browser. As long as the href in your link is prepended with "tel:" the device running the mobile browser is supposed to do the right thing for the platform. In reality I found that, while a fair number of devices from various manufacturers worked as advertised, a fair number didn't. Fortunately, the Android SDK has had a mechanism in place since version 1.0 that allows the app to intercept a loading URL and override the behavior as needed.

This tutorial demonstrates how to intercept the user tapping the phone number link in a web view and the subsequent launching of the dialer app. The idea is that you can use this technique regardless of how the mobile browser on the device does (or does not) interpret the href. Feel free to follow along or download and import the entire project directly into Eclipse.

1. Create a new Android project in Eclipse. Target Android 2.3 (Gingerbread) or better.

2. In the /res/layout folder, add a web view to activity_main.xml.

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview" />

</RelativeLayout>

3. Create a new web view client inside the /src/MainAcitvity.java file and assign it to our web view in on create. The rest is a standard Android intent for opening the dialer and passing it the phone number embedded within the URL.

MainActivity.java
package com.authorwjf.webview_link_intercept;

import android.net.Uri;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.app.Activity;
import android.content.Intent;

public class MainActivity extends Activity {

	private static final String HTML ="<!DOCTYPE html><html><body><a href='tel:867-5309'>Click here to call!</a></body></html>";
	private static final String TEL_PREFIX = "tel:";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		WebView wv = (WebView) findViewById(R.id.webview);
		wv.setWebViewClient(new CustomWebViewClient());
		wv.loadData(HTML, "text/html", "utf-8");
	}
	
	private class CustomWebViewClient extends WebViewClient {
		
		@Override
		public boolean shouldOverrideUrlLoading(WebView wv, String url) {
		    if(url.startsWith(TEL_PREFIX)) {
		        Intent intent = new Intent(Intent.ACTION_DIAL);
		        intent.setData(Uri.parse(url));
		        startActivity(intent);
		        return true;
		    }
		    return false;
		}
	}

	

}

You probably noticed that, while in this instance we are launching the dialer, by returning true in the should override url loading function, we can redirect the app flow any way that's desired. I believe this device-agnostic technique will prove useful to me in a number of scenarios besides the one described here.

If you want to see the web view in action, simply compile and load the APK to a device or emulator.

Figure A

androidwebviewfiga040714.png

Figure B

androidwebviewfigb040714.png

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

0 comments

Editor's Picks