web-dev-qa-db-ja.com

libphonenumber-国コードを知らなくても電話番号をフォーマットする

素晴らしい図書館のように見えるものから多くの良いことを聞いたが、私は微妙な状況にいることに気付いた。

これは、電話番号をデータベースに保存することになっている、私がこれまでに取り組んだ最初のプロジェクトです。

E.164形式について少し読みましたが、この形式を使用してすべての電話番号をデータベースに保存する予定です。

私が直面している問題は、データソースです。データソースを制御できません。私が知っているのは、たくさんの電話番号を受け取っていて、その形式が一貫していないということだけです。国際的な拡張があるものもあれば、ないものもあります。括弧、ハイフン、先頭の0などがあるものもあれば、ないものもあります。

上記のソースから電話番号を抽出し、安全に保管できるようにE.164にフォーマットするにはどうすればよいですか?

国コードにアクセスできないため、国コードを指定せずにPhoneNumberUtil#parse()メソッドを使用してみました。

次の例を見てください。

System.out.printLn("Number -> " + phoneNumberUtil.parse("00336555233634", null).toString())

エラータイプ:INVALID_COUNTRY_CODE。デフォルト領域がないか無効です。

私の例では、番号はフランスの携帯電話の番号です。 0で始まる2つは、フランス国外からダイヤルした場合に機能すると思います。

しかし、国コードが遅れているため、図書館はそれを理解できません。 その特定の電話番号がどこから来ているのかを理解する方法が存在しないということですか?

ドキュメントはそれについて明確に見えます:

public PhoneNumber parse(CharSequence numberToParse, String defaultRegion)

@paramdefaultRegionリージョン。番号の元になると予想されます。 *これは、解析される数値が国際形式で書かれていない場合にのみ使用されます。 *のcountry_code
この場合の番号は、指定されたデフォルトのリージョンの番号として保存されます。番号*が「+」で始まり、その後に国の呼び出しコードが続くことが保証されている場合は、RegionCode.ZZ *またはnullを指定できます。

したがって、+33を追加すると

System.out.printLn("Number -> " + phoneNumberUtil.parse("+336555233634", null).toString())

当然、結果は次のようになります。

番号->国コード:33国番号:336555233634

エンドユーザーがアプリに+で始まらない電話番号を提供した場合、どうすればよいですか?このような状況では、私だけだとは信じられません。

助けてくれてありがとう !

4
Mackovich

E164Formatのみを使用する必要があります。ここではノルウェーを例として取り上げました

電話番号を1つの形式でテストして提供するテストケースがあります。

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);
    }
}
4
VinuBibin

元の電話番号を非運用列RAW_PHONEに保存し、正規のE.164標準化番号をPHONE列("00" -> "+""(" -> "" など)。このようにして、チェックリストと手動修正の準備が整い、変換が改善されます。

想像できるのは、テーブルに2つの電話列があり、2番目の値として別の内線番号-203

国コードで変換が失敗した場合、またはその他の理由で疑わしい場合は、厳密なフィールドに入力しないことをお勧めします。デフォルトのフランスですか、それともユーザーがベルギーに住んでいる場合はどうなりますか?ユーザー登録のソース(場所)がデフォルトの国コードを決定すると主張する人もいるかもしれません。

0
Joop Eggen