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
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 ="Click here to call!";
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
Figure B