Java: libphonenumber

Di - 29 November 2012 - in

In questo articolo parliamo di una libreria disponibile in Java, Javascript e C++ offerta da Google per la gestione dei numeri di telefono, libphonenumber, presentata a Santa Clara, CA USA, in occasione della 35esima Internationalization and Unicode Conference dal 17 al 19 Ottobre 2011.

Questa libreria contiene funzioni per l’analisi, formattazione, memorizzazione e validazione di numeri telefonici internazionali. La versione Java è ottimizzata per essere eseguita su smartphones ed è usata nelle versioni 4.0 e successive di Android.

Diamo uno sguardo alle funzioni e funzionalità principali:

  • Analisi/formattazione/validazione di numeri telefonici di ogni parte del mondo
  • getNumberType restituisce il tipo di numero telefonico basandosi sul numero inserito; riconosce numeri fissi, mobili, gratuiti (e.g. numeri verdi), a pagamento, numeri verso i quali il costo della chiamata è a carico di entrambi gli interlocutori, VoIP e numeri personali
  • isNumberMatch restituisce il valore della probabilità che due numeri siano gli stessi
  • getExampleNumber/getExampleNumberByType fornisce esempi di numeri validi per qualsiasi Paese/Regione; si può specificare, opzionalmente, il tipo di numero di esempio desiderato
  • isPossibleNumber determina se il numero inserito è un numero di telefono o meno basandosi esclusivamente sulla lunghezza del numero stesso
  • isValidNumber esegue la validazione completa del numero basandosi sulla lunghezza e sulle informazioni ottenute dal prefisso
  • AsYouTypeFormatter formatta i numeri durante la composizione
  • findNumbers restituisce i numeri di telefono estratti da un testo in input
  • PhoneNumberOfflineGeocoder fornisce informazioni di tipo geografico relative al numero di telefono

Sono disponibili demo complete in Java ed in JavaScript.

Assumiamo di avere una stringa che rappresenti un numero di telefono svizzero. Vediamo come viene analizzato e normalizzato in un oggetto PhoneNumber (swissNumberProto):

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());
}

A questo punto swissNumberProto contiene:

{
country_code: 41
national_number: 446681800
}

PhotoNumber è una classe auto-generata da phonenumber.proto con dovute modifiche per l’efficienza. Si possono trovare maggiori dettagli sul significato dei campi in phonenumber.proto fra i commenti del codice sorgente.

Passiamo alla validazione di un numero:

boolean isValid = phoneUtil.isValidNumber(swissNumberProto); // vero

I formati disponibili per la formattazione sono INTERNATIONAL, NATIONAL ed E164:

// Stampa "+41 44 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.INTERNATIONAL));
// Stampa "044 668 18 00"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.NATIONAL));
// Stampa "+41446681800"
System.out.println(phoneUtil.format(swissNumberProto, PhoneNumberFormat.E164));

È anche possibile scegliere di formattare il numero nello stesso formato in cui viene chiamato da un altro Paese:

// Stampa "011 41 44 668 1800", ovvero il numero nella forma statunitense.
System.out.println(phoneUtil.formatOutOfCountryCallingNumber(swissNumberProto, "US"));

Vediamo la classe AsYouTypeFormatter in azione:

PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("US");
System.out.println(formatter.inputDigit('6'));  // Stampa "6"
...  // Si inseriscono altre cifre
System.out.println(formatter.inputDigit('3'));  // Stampa "650 253"

Ottenere informazioni geografiche offline:

PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
// Stampa "Zurich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ENGLISH);
// Stampa "Zürich"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.GERMAN);
// Stampa "Zurigo"
System.out.println(geocoder.getDescriptionForNumber(swissNumberProto, Locale.ITALIAN);

Altri esempi si possono trovare fra gli unittests nella repository di libphonenumber; esistono, fra gli altri, due portings interessanti in C# e Python; per quest’ultimo, ecco un esempio su come si ottengono le informazioni geografiche:

from phonenumbers.geocoder import area_description_for_number
ch_number = phonenumbers.parse("0431234567", "CH")
print repr(area_description_for_number(ch_number, "de"))
# u'Z\\xfcrich'
print repr(area_description_for_number(ch_number, "en"))
# u'Zurich'
print repr(area_description_for_number(ch_number, "fr"))
# u'Zurich'
print repr(area_description_for_number(ch_number, "it"))
# u'Zurigo'

Fonti code.google.com, GitHub

Leave a Reply

Claudio d'Angelis Articolo scritto da

Programmatore e studente di Informatica, appassionato di musica, web e sistemi UNIX. Collabora con Googlab dall'Ottobre 2012.

Contatta l'autore

Previous post:

Next post: