谷歌的libphonenumber代码学习
1. 电话号码 定义
phonenumber.proto
// Definition of protocol buffer for representing international telephone numbers.
syntax = "proto2";
option java_package = "com.google.i18n.phonenumbers";
option optimize_for = LITE_RUNTIME;
package i18n.phonenumbers;
message PhoneNumber {
// 国家码,例如中国的国家码是86,美国的国家码是1。
required int32 country_code = 1;
// 在国家内部的电话号码,也就是去掉国家码后的电话号码。
// 没有前缀0,没有空格等
required uint64 national_number = 2;
// 分机号,用于在一个电话系统内部区分不同的线路。
optional string extension = 3;
// 意大利电话号码的前导零,意大利的电话号码有时候会以一个或多个零开头。
optional bool italian_leading_zero = 4;
// 前导零的数量,用于记录电话号码开头的零的数量。
optional int32 number_of_leading_zeros = 8 [ default = 1 ];
// 原始的电话号码字符串,也就是用户输入的电话号码字符串。
optional string raw_input = 5;
// 表示电话号码中国家码的来源
enum CountryCodeSource {
// 默认值,表示国家码的来源未知或未指定。
UNSPECIFIED = 0;
// 表示国家码是从带有加号的电话号码中解析出来的。
// The country_code is derived based on a phone number with a leading "+",
// e.g. the French number "+33 1 42 68 53 00".
FROM_NUMBER_WITH_PLUS_SIGN = 1;
// 表示国家码是从带有国际直拨前缀的电话号码中解析出来的
// The country_code is derived based on a phone number with a leading IDD,
// e.g. the French number "011 33 1 42 68 53 00", as it is dialled from US.
FROM_NUMBER_WITH_IDD = 5;
// 表示国家码是从不带有加号的电话号码中解析出来的
// The country_code is derived based on a phone number without a leading
// "+", e.g. the French number "33 1 42 68 53 00" when defaultCountry is
// supplied as France.
FROM_NUMBER_WITHOUT_PLUS_SIGN = 10;
// 表示国家码是使用默认的国家码。例如,当解析的电话号码没有明确的国家码,且用户设置了默认的国家码时,会使用这个默认的国家码。
FROM_DEFAULT_COUNTRY = 20;
}
// 国家码的来源,用于记录国家码是从哪里得到的。
optional CountryCodeSource country_code_source = 6;
// 在国内优先使用的运营商代码,用于记录在一个国家内部,优先使用哪个运营商的网络。
optional string preferred_domestic_carrier_code = 7;
}
// Examples:
//
// Google MTV, +1 650-253-0000, (650) 253-0000
// country_code: 1
// national_number: 6502530000
//
// Google Paris, +33 (0)1 42 68 53 00, 01 42 68 53 00
// country_code: 33
// national_number: 142685300
//
// Google Beijing, +86-10-62503000, (010) 62503000
// country_code: 86
// national_number: 1062503000
//
// Google Italy, +39 02-36618 300, 02-36618 300
// country_code: 39
// national_number: 236618300
// italian_leading_zero: true
2.常用函数
2.1 parse:根据电话字符串和国家解析为PhoneNumber
1、使用示例
String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
At this point, swissNumberProto contains:
{
"country_code": 41,
"national_number": 446681800
}
2、函数说明
parse函数非常宽松,在输入文本(原始输入)中查找数字,忽略标点符号、空白,以及数字之前的任何文本(例如,前导“Tel:”),并修剪非数字位。它将接受任何格式的数字(E164、国家、国际等)。不会对该数字是否实际上是特定区域的有效电话进行验证。
- 参数numberToParse:试图解析的数字。它可以包含+、(和-等格式,以及电话号码扩展名。
- 参数defaultRegion:数字不是国际格式时,才使用此选项。在这种情况下,数字的country_code将存储为所提供的默认地区的country-code。如果该号码保证以“+”开头,后跟国家/地区呼叫代码,则可以提供RegionCode.ZZ或null。
2.2 isValidNumber:判断电话是否为有效数字
1、使用示例
String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
boolean isValid = phoneUtil.isValidNumber(swissNumberProto); // returns true
2、函数说明
该函数仅判断 电话号码是否符合号码规范,并不能保证该电话号码一定在使用。
2.3 format:电话格式化
1、使用示例
String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
// Produces "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Produces "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Produces "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));
2、函数说明
String format(PhoneNumber number, PhoneNumberFormat numberFormat)
public enum PhoneNumberFormat {
E164,
INTERNATIONAL,
NATIONAL,
RFC3966
}
2.4 formatNumberForMobileDialing 获取可拨打电话
1、使用示例
public void testFormatNumberForMobileDialing() {
PhoneNumber CO_FIXED_LINE =
new PhoneNumber().setCountryCode(57).setNationalNumber(6012345678L);
PhoneNumber DE_NUMBER =
new PhoneNumber().setCountryCode(49).setNationalNumber(30123456L);
honeNumber US_TOLLFREE =
new PhoneNumber().setCountryCode(1).setNationalNumber(8002530000L);
// Numbers are normally dialed in national format in-country, and international format from
// outside the country.
assertEquals("6012345678",
phoneUtil.formatNumberForMobileDialing(CO_FIXED_LINE, RegionCode.CO, false));
assertEquals("+4930123456",
phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.CH, false));
assertEquals("800 253 0000",
phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US,
true /* keep formatting */));
}
2、函数说明
//regionCallingFrom:呼叫人所在地的二字母地区码
//withFormatting:是否应使用格式符号(如空格和破折号)返回数字。
String formatNumberForMobileDialing(PhoneNumber number, String regionCallingFrom,
boolean withFormatting)
返回一个格式化为可以从特定地区的移动电话拨打的号码。
注意: 如果无法从该地区拨打该号码(例如,一些国家/地区阻止在该国家/地区以外拨打免费电话),该方法将返回一个空字符串。
- 如果 呼叫人所在地区 和 电话所在地 是同一个地区,就返回 国内号码格式
- 如果 呼叫人所在地区 和 电话所在地 不是同一个地区,就返回 国际化号码格式