Wednesday, June 26, 2013

Dealing with international numbers in Android, Java

If you are writing an application that needs to use international or national phone numbers, this post will show you how international and national numbers work, and how you can correctly handle any phone number whatsoever with libphonenumber, a Java library.


Here is how international numbers work:


International Access Code  + Country Calling Code +  National Number.

For example, here is a call from the US, dialing outside of the US, into London:


011
International Access Code
44
Country Calling Code
20 1234 5678
National Number

The international access code for the US (011) dials outside of the US, the country calling code for the United Kingdom (44) dials into the United Kingdom, and the national number (2012345678) dials the local London number. Here is a resource with international access codes ( also called international call prefix) for all countries: International Access Codes. Here is a resource with country calling codes for all countries: Country Calling Codes.

Alternatively, you can dial a plus sign (+) into a mobile phone instead of the international access code, and the phone will dial the country specific international access code on its own. The equivalent for the above example with the plus sign is: +442012345678. For international calls, Android phones will display incoming call numbers in this format (the plus sign followed by the country calling code, followed by the national number). Sometimes, depending on the phone, Android uses this format for local/national calls also, and sometimes it will display just the national number.

To parse an international phone number correctly from any of the above formats in Java, use the Java libphonenumber library written by Google. This library has its equivalents in other languages such as Php, .NET, Javascript, and iOS. The Java and Php version were tested here. The only version that can be guaranteed by this post to be reliable is the Java version. If you are dialing the number above:
PhoneNumberUtil p = PhoneNumberUtil.getInstance();
String number = "011442012345678"; //can also be +442012345678
String region = "US"; 
PhoneNumber pn = p.parse(number, region);
String nationalnumber = String.valueOf(pn.getNationalNumber()); //2012345678
String countrycallingcode =  String.valueOf(pn.getCountryCode()); // country code for Great Britain
The "US" string is the ISO country code for the United States. A list of ISO country codes can be found here: ISO codes. To get the ISO country code within Android:
TelephonyManager t = TelephonyManager.getInstance();
String country = t.getNetworkCountryIso();
if(country != null) {
country = country.toUpperCase(); // must be upper case for libphonenumber parse method
}
The reason "US" is used is because the number is being dialed from the US. If you are parsing the incoming call in London, from the US, the number will be handled in Android as +442012345678. If the number starts with a plus sign, the region is ignored. The receiving phone should use its own ISO code ("GB") if the number does not start with a plus sign.

Here is how national numbers work:


Trunk Prefix  +  National Number.
A list of country specific trunk prefixes can be found here: Trunk Prefix , or here . The trunk prefix for most countries outside of North America is 0. The trunk prefix for most countries inside North America is 1. For example, here is a call from one phone inside the UK to another inside the UK:

0
Trunk Prefix
20 1234 5678
National Number

The trunk prefix is sometimes omitted. Parsing a national number is the same as parsing an international number. The libphonenumber will recognize if there is a trunk prefix, and correctly identify the country code:
PhoneNumberUtil p = PhoneNumberUtil.getInstance();
String number = "02012345678"; //can also be 2012345678
String region = "GB"; 
PhoneNumber pn = p.parse(number, region);
String nationalnumber = String.valueOf(pn.getNationalNumber()); //2012345678
String countrycallingcode =  String.valueOf(pn.getCountryCode()); //44

The Php version was tested too, and people reading this may have a different experience. The problem with it was it threw an exception for a number like this: 2122322323 with Iso region code "US".

In conclusion, to parse a number with libphonenumber, remove all non digit characters from the number string, get the ISO code of the region from which the number is being dialed (if it is an outgoing number), or the region in which the number is being received (for incoming numbers). Then call the parse method.

4 comments:

  1. Suppose I have a number which may be either in international format or national format. I also don't know the region cause it may be any region in the world. So how can I get the national number excluding the country code?

    ReplyDelete
  2. Get an international phone number from CallHippo at an affordable price plan starting from $6.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Various utilities for dealing with phone number strings.Google provides a library for working with phone numbers.Google's common Java, C++ and JavaScript library for parsing, formatting, and validatinginternational phone numbers.

    ReplyDelete