Googleの電話番号を扱うライブラリlibphonenumberを使ってみたのでメモ
Androidアプリの開発で電話番号を扱いたくて、googleのlibphonenumberを使ってみたのでまとめます。
電話番号について
まずは、電話番号そのものについてちょっと調べてみました。
例えば、080-1234-5678
なんていう番号があったとします。海外からこの電話番号にかけようとすると、+81-80-1234-5678
となります。
これは、ITU-T(International Telecommunication Union Telecommunication Standardization Sector)が勧告するE.164に沿っていて、調べてみると意外と奥が深かったりします。
ドキュメントはここに落ちているので、気合いの入った方は是非読んでみてください。
(E.164 : The international public telecommunication numbering plan)
https://www.itu.int/rec/T-REC-E.164-201011-I/en
とりあえずパースしたい僕としては、ドキュメントのこの図だけ分かっておけば十分そうです。
総務省の資料もありました。これだけで十分でしたね。
(電気通信番号制度概要)
http://www.soumu.go.jp/main_sosiki/joho_tsusin/policyreports/joho_tsusin/bango/pdf/061012_4_s8.pdf
結局、必要そうな情報は以下の三点です。
- 電話番号には世界共通の勧告がある
- 先頭には1〜3桁のCC(国番号)が必要
- 国際番号を除けば海外と電話番号が被る可能性がある?
- 電話番号は最大で15桁
libphonenumber
ようやく本題です。Google Internationalizationが提供するライブラリで、電話番号をパースするのに必要なことをよしなにやってくれます。
Android限定というわけではなく、Java、C++、JS向けのライブラリのようです。
何ができるの
電話番号のパースをしたい
# パース fun libphonenumberTest_parse() { var msn = "08012345678" println(phoneNumberUtil.parse(msn, "JP")) msn = "818012345678" println(phoneNumberUtil.parse(msn, "JP")) msn = "+818012345678" println(phoneNumberUtil.parse(msn, "JP")) msn = "+81 80 1234 5678" println(phoneNumberUtil.parse(msn, "JP")) msn = "+81-80-1234-5678" println(phoneNumberUtil.parse(msn, "JP")) msn = "080(1234)5678" println(phoneNumberUtil.parse(msn, "JP")) msn = "080.1234.5678" println(phoneNumberUtil.parse(msn, "JP")) } # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 # => Country Code: 81 National Number: 8012345678 fun libphonenumberTest_parse_withInvalidRegion() { val msn = "+818012345678" println(phoneNumberUtil.parse(msn, "US")) } # => Country Code: 1 National Number: 818012345678
電話番号のフォーマットをしたい
# フォーマット fun libphonenumberTest_format() { /* public enum PhoneNumberFormat { E164, INTERNATIONAL, NATIONAL, RFC3966 } */ val msn = phoneNumberUtil.parse("08012345678", "JP") println("E164: " + phoneNumberUtil.format(msn, PhoneNumberUtil.PhoneNumberFormat.E164)) println("INTERNATIONAL: " + phoneNumberUtil.format(msn, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL)) println("NATIONAL: " + phoneNumberUtil.format(msn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL)) println("RFC3966: " + phoneNumberUtil.format(msn, PhoneNumberUtil.PhoneNumberFormat.RFC3966)) } # => E164: +818012345678 # => INTERNATIONAL: +81 80-1234-5678 # => NATIONAL: 080-1234-5678 # => RFC3966: tel:+81-80-1234-5678
電話番号のタイプを知りたい: getNumberType
固定電話、携帯電話、フリーダイヤル、、、など、電話番号のタイプ判別ができます
fun libphonenumberTest_getNumberType() { val mobile = phoneNumberUtil.parse("08012345678", "JP") val fixed = phoneNumberUtil.parse("81312345678", "JP") val free = phoneNumberUtil.parse("0120123456", "JP") println("mobile: " + phoneNumberUtil.getNumberType(mobile)) println("fixed: " + phoneNumberUtil.getNumberType(fixed)) println("free: " + phoneNumberUtil.getNumberType(free)) } # => mobile: MOBILE # => fixed: FIXED_LINE # => free: TOLL_FREE
電話番号の一致をチェックしたいisNumberMatch
2つの番号が同一かどうか、その信頼性を判断します。どのスケールでなら一致しているかを判断してくれるみたいですね。
fun libphonenumberTest_isNumberMatch() { println(phoneNumberUtil.isNumberMatch("+81334311234", "+81334311234")) println(phoneNumberUtil.isNumberMatch("+81334311234", "0334311234")) println(phoneNumberUtil.isNumberMatch("+81334311234", "34311234")) println(phoneNumberUtil.isNumberMatch("+81334311234", "+818012345678")) println(phoneNumberUtil.isNumberMatch("+81334311234", "0")) } # => EXACT_MATCH # => NSN_MATCH # => SHORT_NSN_MATCH # => NO_MATCH # => NOT_A_NUMBER
電話番号のバリデーションをしたい: isPossibleNumber
, isValidNumber
電話番号の長さだけを見て、電話番号として成立しているかどうかを判断します。
isPossibleNumber
は電話番号の長さを、isValidNumber
は加えてprefixまで見ているらしく、前者の方が速いみたいです。
fun libphonenumberTest_isPossibleNumber() { val msn = phoneNumberUtil.parse("08012345678", "JP") val justNumber = phoneNumberUtil.parse("00000", "JP") val just15Numbers = phoneNumberUtil.parse("000000000000000", "JP") println(phoneNumberUtil.isPossibleNumber(msn)) println(phoneNumberUtil.isPossibleNumber(justNumber)) println(phoneNumberUtil.isPossibleNumber(just15Numbers)) } # => true # => false # => true fun libphonenumberTest_isValidNumber() { val msn = phoneNumberUtil.parse("08012345678", "JP") val justNumber = phoneNumberUtil.parse("00000", "JP") val just15Numbers = phoneNumberUtil.parse("000000000000000", "JP") println(phoneNumberUtil.isValidNumber(msn)) println(phoneNumberUtil.isValidNumber(justNumber)) println(phoneNumberUtil.isValidNumber(just15Numbers)) } # => true # => false # => false
終わりに
今回紹介したものはほんの一部で、他にもダミーの電話番号を生成してくれたり、文章中から電話番号を抽出してくれたり、など至れり尽くせりなライブラリになっています。
電話番号というと、個人情報の中でもなかなか扱いづらく収集しづらいものに分類されてしまいがちなので、なかなかさわる機会ってないのがちょっと残念です。
ついでに、先日、キャリアがRCS準拠のサービスを始めるとのニュースがありました。
これ使って遊べたら面白そうだなぁ。
おまけ
電話番号がどの企業に割り当てられているか、が一覧になっています。携帯の電話番号だとMNPのために判断が難しくなっていますが。。。 (電気通信番号指定状況) http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html