diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java index cab9dc14d3310..0732c5153610d 100644 --- a/core/java/android/pim/vcard/ContactStruct.java +++ b/core/java/android/pim/vcard/ContactStruct.java @@ -471,20 +471,24 @@ public class ContactStruct { } StringBuilder builder = new StringBuilder(); String trimed = data.trim(); - int length = trimed.length(); - for (int i = 0; i < length; i++) { - char ch = trimed.charAt(i); - if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) { - builder.append(ch); + final String formattedNumber; + if (type == Phone.TYPE_PAGER) { + formattedNumber = trimed; + } else { + final int length = trimed.length(); + for (int i = 0; i < length; i++) { + char ch = trimed.charAt(i); + if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) { + builder.append(ch); + } } - } - // Use NANP in default when there's no information about locale. - final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ? - PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP); - final String formattedPhoneNumber = - PhoneNumberUtils.formatNumber(builder.toString(), formattingType); - PhoneData phoneData = new PhoneData(type, formattedPhoneNumber, label, isPrimary); + // Use NANP in default when there's no information about locale. + final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ? + PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP); + formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType); + } + PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary); mPhoneList.add(phoneData); } @@ -856,7 +860,8 @@ public class ContactStruct { } } else if (propName.equals(Constants.PROPERTY_TEL)) { final Collection typeCollection = paramMap.get(Constants.PARAM_TYPE); - final Object typeObject = VCardUtils.getPhoneTypeFromStrings(typeCollection); + final Object typeObject = + VCardUtils.getPhoneTypeFromStrings(typeCollection, propValue); final int type; final String label; if (typeObject instanceof Integer) { diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java index c59e258081d84..8da23a42ab65e 100644 --- a/core/java/android/pim/vcard/VCardUtils.java +++ b/core/java/android/pim/vcard/VCardUtils.java @@ -98,7 +98,11 @@ public class VCardUtils { * Returns Interger when the given types can be parsed as known type. Returns String object * when not, which should be set to label. */ - public static Object getPhoneTypeFromStrings(Collection types) { + public static Object getPhoneTypeFromStrings(Collection types, + String number) { + if (number == null) { + number = ""; + } int type = -1; String label = null; boolean isFax = false; @@ -117,7 +121,20 @@ public class VCardUtils { } Integer tmp = sKnownPhoneTypeMap_StoI.get(typeString); if (tmp != null) { - type = tmp; + final int typeCandidate = tmp; + // TYPE_PAGER is prefered when the number contains @ surronded by + // a pager number and a domain name. + // e.g. + // o 1111@domain.com + // x @domain.com + // x 1111@ + final int indexOfAt = number.indexOf("@"); + if ((typeCandidate == Phone.TYPE_PAGER + && 0 < indexOfAt && indexOfAt < number.length() - 1) + || type < 0 + || type == Phone.TYPE_CUSTOM) { + type = tmp; + } } else if (type < 0) { type = Phone.TYPE_CUSTOM; label = typeString; diff --git a/tests/AndroidTests/res/raw/v30_comma_separated.vcf b/tests/AndroidTests/res/raw/v30_comma_separated.vcf new file mode 100644 index 0000000000000..98a7f20588a17 --- /dev/null +++ b/tests/AndroidTests/res/raw/v30_comma_separated.vcf @@ -0,0 +1,5 @@ +BEGIN:VCARD +VERSION:3.0 +N:F;G;M;; +TEL;TYPE=PAGER,WORK,MSG:6101231234@pagersample.com +END:VCARD diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java index 1aa334a22355c..f447c771ca47e 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardImporterTests.java @@ -18,7 +18,6 @@ package com.android.unit_tests.vcard; import android.content.ContentValues; import android.pim.vcard.VCardConfig; -import android.pim.vcard.VCardParser_V21; import android.pim.vcard.exception.VCardException; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.CommonDataKinds.Email; @@ -35,7 +34,6 @@ import com.android.unit_tests.R; import com.android.unit_tests.vcard.PropertyNodesVerifierElem.TypeSet; import java.io.IOException; -import java.io.InputStream; import java.util.Arrays; public class VCardImporterTests extends VCardTestsBase { @@ -866,8 +864,9 @@ public class VCardImporterTests extends VCardTestsBase { } public void testV21Japanese2_Type_Generic_Utf8() throws IOException, VCardException { - ImportVerifierElem verifier = new ImportVerifierElem(); - verifier.addExpected(StructuredName.CONTENT_ITEM_TYPE) + ImportVerifier verifier = new ImportVerifier(); + ImportVerifierElem elem = verifier.addImportVerifierElem(); + elem.addExpected(StructuredName.CONTENT_ITEM_TYPE) .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4") .put(StructuredName.GIVEN_NAME, "\u30ED\u30A4\u30C9\u0031") .put(StructuredName.DISPLAY_NAME, @@ -877,7 +876,7 @@ public class VCardImporterTests extends VCardTestsBase { .put(StructuredName.PHONETIC_FAMILY_NAME, "\uFF71\uFF9D\uFF84\uFF9E\uFF73") .put(StructuredName.PHONETIC_GIVEN_NAME, "\uFF9B\uFF72\uFF84\uFF9E\u0031"); - verifier.addExpected(StructuredPostal.CONTENT_ITEM_TYPE) + elem.addExpected(StructuredPostal.CONTENT_ITEM_TYPE) .put(StructuredPostal.POSTCODE, "150-8512") .put(StructuredPostal.NEIGHBORHOOD, "\u6771\u4EAC\u90FD\u6E0B\u8C37\u533A\u685C" + @@ -890,7 +889,7 @@ public class VCardImporterTests extends VCardTestsBase { "\u30EB\u30EA\u30A2\u30F3\u30BF\u30EF\u30FC" + "\u0036\u968E 150-8512") .put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME); - verifier.addExpected(Note.CONTENT_ITEM_TYPE) + elem.addExpected(Note.CONTENT_ITEM_TYPE) .put(Note.NOTE, "\u30E1\u30E2"); verifier.verify(R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8); } @@ -1013,4 +1012,28 @@ public class VCardImporterTests extends VCardTestsBase { .put(Phone.NUMBER, "20"); verifier.verify(R.raw.v21_multiple_entry, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS); } + + public void testPagerV30_Parse() throws IOException, VCardException { + PropertyNodesVerifier verifier = new PropertyNodesVerifier(this); + verifier.addPropertyNodesVerifierElem() + .addNodeWithOrder("VERSION", "3.0") + .addNodeWithOrder("N", Arrays.asList("F", "G", "M", "", "")) + .addNodeWithOrder("TEL", "6101231234@pagersample.com", + new TypeSet("WORK", "MSG", "PAGER")); + verifier.verify(R.raw.v30_comma_separated, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8); + } + + public void testPagerV30() throws IOException, VCardException { + ImportVerifier verifier = new ImportVerifier(); + ImportVerifierElem elem = verifier.addImportVerifierElem(); + elem.addExpected(StructuredName.CONTENT_ITEM_TYPE) + .put(StructuredName.FAMILY_NAME, "F") + .put(StructuredName.MIDDLE_NAME, "M") + .put(StructuredName.GIVEN_NAME, "G") + .put(StructuredName.DISPLAY_NAME, "G M F"); + elem.addExpected(Phone.CONTENT_ITEM_TYPE) + .put(Phone.TYPE, Phone.TYPE_PAGER) + .put(Phone.NUMBER, "6101231234@pagersample.com"); + verifier.verify(R.raw.v30_comma_separated, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8); + } }