我从一个很棒的图书馆那里听到了很多好处,但是我发现自己处境艰难。
这是我工作过的第一个项目,应该将电话号码存储在数据库中。
我已经阅读了一些有关 E.164 格式的信息,并且确实打算将使用该格式的所有电话号码存储在数据库中。
我面临的问题是数据源。我无法控制数据源。我所知道的是,我收到了一堆电话号码,它们的格式不一致。有些具有国际扩展名,有些则没有。有些带有括号,连字符,前导0等,有些则没有。
我怎么可能从上述来源提取电话号码,将其格式化为E.164,以便我可以安全地存储它们?
由于我无法访问该信息,因此我尝试使用PhoneNumberUtil#parse()
方法而不提供国家/地区代码。
看看下面的例子:
System.out.printLn("Number -> " + phoneNumberUtil.parse("00336555233634", null).toString())
错误类型:INVALID_COUNTRY_CODE。默认区域缺失或无效。
在我的示例中,该号码是法国手机的号码。我相信,如果您从法国境外拨打电话,两个开头的0
可以使用。
但是该库无法理解它,因为它正在延迟国家代码。 这是否意味着没有办法了解特定电话号码的来源?
文档似乎对此很清楚:
public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)
@param defaultRegion区域,我们期望该数字为 从。仅当*解析的数字不是 以国际格式编写。 *
的country_code 在这种情况下,编号将存储为默认区域的编号 提供。如果数字*保证以'+'开头 随后是国家/地区代码,然后是RegionCode.ZZ *或 可以提供null。
因此,如果添加+33
System.out.printLn("Number -> " + phoneNumberUtil.parse("+336555233634", null).toString())
然后自然得出的结果是:
号码->国家/地区代码:33国家/地区号码:336555233634
如果最终用户向我的应用提供的电话号码不是以+
开头,该怎么办?如果发生这种情况,我不敢相信自己是唯一的人。
感谢您的帮助!
答案 0 :(得分:1)
您只需要使用E164Format。这里我以挪威为例
我有一个测试用例,可以用一种格式进行测试并给出电话号码。
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);
}
}
和测试用例如下。
// 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);
}
}
答案 1 :(得分:0)
将原始电话号码存储在RAW_PHONE的不可操作列中,并将标准的E.164标准化号码存储在PHONE列中("00" -> "+"
,"(" -> ""
等)。这样,您就可以准备检查清单和手动更正,并改善转换。
可以想象,表中有两个电话栏,而另一个分机号-203
作为第二个值。
如果根据国家/地区代码进行的转换失败或存在其他疑问,最好不要填写严格的字段。是默认的法国,还是用户居住在比利时时的默认值? 有人可能会说用户注册的来源(位置)决定了默认的国家/地区代码。