I have heard a lot of good from what appears to be an awesome library but I find myself in a delicate situation.
This is the first project I have ever worked where I am supposed to store phone numbers in a database.
I have read a bit about the E.164 format and I do intend to store all phone numbers using this format in my database.
The problem I am facing, is the data source. I have no control over the data source. All I known is that I am receiving a bunch of phone numbers and their format is not consistent. Some have the international extension, some don't. Some have parenthesis, hyphens, leading 0, etc. some don't.
How could I possibly extract the phone numbers from said source, format them into E.164 so that I can store them safely ?
I have tried using the PhoneNumberUtil#parse()
method without providing the country code, since I don't have access to that information.
Have a look at the following example:
System.out.printLn("Number -> " + phoneNumberUtil.parse("00336555233634", null).toString())
Error type: INVALID_COUNTRY_CODE. Missing or invalid default region.
In my example, the number is that of french mobile phone. The two starting 0
works if you dial from outside France, I believe.
But the library cannot understand it as it is laking the country code. Does that mean there does not exist a way to understand where that particular phone number is coming from ?
The documentation seems clear about it :
public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)
@param defaultRegion region that we are expecting the number to be from. This is only used if * the number being parsed is not written in international format. The country_code for the *
number in this case would be stored as that of the default region supplied. If the number * is guaranteed to start with a '+' followed by the country calling code, then RegionCode.ZZ * or null can be supplied.
So, if add the +33
System.out.printLn("Number -> " + phoneNumberUtil.parse("+336555233634", null).toString())
Then naturally the result is:
Number -> Country Code: 33 National Number: 336555233634
What should / can I do if the end-user supplies my app with phone numbers that do not start with +
? I cannot believe I am the only one if this situation.
Thanks for the help !
To format phone numbers in the US, Canada, and other NANP (North American Numbering Plan) countries, enclose the area code in parentheses followed by a nonbreaking space, and then hyphenate the three-digit exchange code with the four-digit number.
A phone number in full international format includes a plus sign (+) followed by the country code, city code, and local phone number.
Mobile numbers which are not local need to be prefixed by a 0 while dialing, or by +91 (91 is the country code for India). A mobile number written as +91-AAAAA BBBBB is valid throughout India, and in other countries where the + is recognized as a prefix to the country code.
You need to use E164Format only. Here I took Norway as example
I have test case which tests and give the phone number in one format.
public static String getE164FormattedMobileNumber(String mobile, String locale)
throws PhoneNumberFormatException {
try {
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
PhoneNumber phoneProto = phoneUtil.parse(mobile, locale);
if (phoneUtil.isValidNumber(phoneProto)
&& phoneUtil.isPossibleNumberForType(phoneProto, PhoneNumberType.MOBILE)) {
return phoneUtil.format(phoneProto, PhoneNumberFormat.E164);
}
throw new PhoneNumberFormatException(
"Mobile number is invalid with the provided locale");
} catch (NumberParseException e) {
throw new PhoneNumberFormatException("Error in parsing mobile number", e);
}
}
and the test case as follows.
// this is the test mobile used
private String expectedMobileNumber = "+4746205615";
private List<String> sucessMobileNumbers;
private List<String> failMobileNumbers;
public PhoneNumberE164FormatTest() {
sucessMobileNumbers =
Arrays.asList(
"46205615",
"004746205615",
"+4746205615",
"4746205615",
"46205615",
"+47 46205615",
"462 05 615");
failMobileNumbers = Arrays.asList("abcdsds3434", "abcdsds343?#4", "21448410", "9946739087");
}
@Test
public void e164FormattedMobileNumbersSucessCase() throws PhoneNumberFormatException {
for (String mobileNumber : sucessMobileNumbers) {
Assert.assertEquals(
expectedMobileNumber,
(PhoneNumberUtils.getE164FormattedMobileNumber(mobileNumber, NO)));
}
}
@Test(expected = PhoneNumberFormatException.class)
public void e164FormattedMobileNumbersFailCase() throws PhoneNumberFormatException {
for (String mobileNumber : failMobileNumbers) {
PhoneNumberUtils.getE164FormattedMobileNumber(mobileNumber, NO);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With