Loading core/java/android/pim/vcard/VCardBuilder.java +34 −15 Original line number Diff line number Diff line Loading @@ -642,22 +642,18 @@ public class VCardBuilder { if (TextUtils.isEmpty(phoneNumber)) { continue; } int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE); if (type == Phone.TYPE_PAGER) { // PAGER number needs unformatted "phone number". final int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE); if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) { phoneLineExists = true; if (!phoneSet.contains(phoneNumber)) { phoneSet.add(phoneNumber); appendTelLine(type, label, phoneNumber, isPrimary); } } else { // The entry "may" have several phone numbers when the contact entry is // corrupted because of its original source. // // e.g. I encountered the entry like the following. // "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami); ..." // This kind of entry is not able to be inserted via Android devices, but // possible if the source of the data is already corrupted. List<String> phoneNumberList = splitIfSeveralPhoneNumbersExist(phoneNumber); final List<String> phoneNumberList = splitAndTrimPhoneNumbers(phoneNumber); if (phoneNumberList.isEmpty()) { continue; } Loading @@ -670,7 +666,7 @@ public class VCardBuilder { phoneSet.add(actualPhoneNumber); appendTelLine(type, label, formattedPhoneNumber, isPrimary); } } } // for (String actualPhoneNumber : phoneNumberList) { } } } Loading @@ -682,15 +678,38 @@ public class VCardBuilder { return this; } private List<String> splitIfSeveralPhoneNumbersExist(final String phoneNumber) { List<String> phoneList = new ArrayList<String>(); /** * <p> * Splits a given string expressing phone numbers into several strings, and remove * unnecessary characters inside them. The size of a returned list becomes 1 when * no split is needed. * </p> * <p> * The given number "may" have several phone numbers when the contact entry is corrupted * because of its original source. * e.g. "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami)" * </p> * <p> * This kind of "phone numbers" will not be created with Android vCard implementation, * but we may encounter them if the source of the input data has already corrupted * implementation. * </p> * <p> * To handle this case, this method first splits its input into multiple parts * (e.g. "111-222-3333 (Miami)", "444-555-6666 (Broward", and 305653-6796 (Miami)") and * removes unnecessary strings like "(Miami)". * </p> * <p> * Do not call this method when trimming is inappropriate for its receivers. * </p> */ private List<String> splitAndTrimPhoneNumbers(final String phoneNumber) { final List<String> phoneList = new ArrayList<String>(); StringBuilder builder = new StringBuilder(); final int length = phoneNumber.length(); for (int i = 0; i < length; i++) { final char ch = phoneNumber.charAt(i); // TODO: add a test case for string with '+', and care the other possible issues // which may happen by ignoring non-digits other than '+'. if (Character.isDigit(ch) || ch == '+') { builder.append(ch); } else if ((ch == ';' || ch == '\n') && builder.length() > 0) { Loading core/java/android/pim/vcard/VCardConfig.java +30 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.pim.vcard; import android.telephony.PhoneNumberUtils; import android.util.Log; import java.util.HashMap; Loading Loading @@ -190,6 +191,30 @@ public class VCardConfig { */ public static final int FLAG_REFRAIN_IMAGE_EXPORT = 0x02000000; /** * <P> * The flag indicating the vCard composer does touch nothing toward phone number Strings * but leave it as is. * </P> * <P> * The vCard specifications mention nothing toward phone numbers, while some devices * do (wrongly, but with innevitable reasons). * For example, there's a possibility Japanese mobile phones are expected to have * just numbers, hypens, plus, etc. but not usual alphabets, while US mobile phones * should get such characters. To make exported vCard simple for external parsers, * we have used {@link PhoneNumberUtils#formatNumber(String)} during export, and * removed unnecessary characters inside the number (e.g. "111-222-3333 (Miami)" * becomes "111-222-3333"). * Unfortunate side effect of that use was some control characters used in the other * areas may be badly affected by the formatting. * </P> * <P> * This flag disables that formatting, affecting both importer and exporter. * If the user is aware of some side effects due to the implicit formatting, use this flag. * </P> */ public static final int FLAG_REFRAIN_PHONE_NUMBER_FORMATTING = 0x02000000; //// The followings are VCard types available from importer/exporter. //// /** Loading Loading @@ -431,6 +456,10 @@ public class VCardConfig { return sJapaneseMobileTypeSet.contains(vcardType); } /* package */ static boolean refrainPhoneNumberFormatting(final int vcardType) { return ((vcardType & FLAG_REFRAIN_PHONE_NUMBER_FORMATTING) != 0); } public static boolean needsToConvertPhoneticString(final int vcardType) { return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0); } Loading core/java/android/pim/vcard/VCardEntry.java +2 −3 Original line number Diff line number Diff line Loading @@ -488,7 +488,7 @@ public class VCardEntry { final StringBuilder builder = new StringBuilder(); final String trimed = data.trim(); final String formattedNumber; if (type == Phone.TYPE_PAGER) { if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) { formattedNumber = trimed; } else { final int length = trimed.length(); Loading @@ -500,8 +500,7 @@ public class VCardEntry { } // Use NANP in default when there's no information about locale. final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ? PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP); final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType); formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType); } PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary); Loading core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java +10 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,16 @@ public class VCardExporterTests extends VCardTestsBase { testPhoneBasicCommon(V30); } public void testPhoneRefrainFormatting() { mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING); mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)") .put(Phone.TYPE, Phone.TYPE_HOME); mVerifier.addPropertyNodesVerifierElemWithEmptyName() .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)", new TypeSet("HOME")); } /** * Tests that vCard composer emits corresponding type param which we expect. */ Loading Loading
core/java/android/pim/vcard/VCardBuilder.java +34 −15 Original line number Diff line number Diff line Loading @@ -642,22 +642,18 @@ public class VCardBuilder { if (TextUtils.isEmpty(phoneNumber)) { continue; } int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE); if (type == Phone.TYPE_PAGER) { // PAGER number needs unformatted "phone number". final int type = (typeAsObject != null ? typeAsObject : DEFAULT_PHONE_TYPE); if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) { phoneLineExists = true; if (!phoneSet.contains(phoneNumber)) { phoneSet.add(phoneNumber); appendTelLine(type, label, phoneNumber, isPrimary); } } else { // The entry "may" have several phone numbers when the contact entry is // corrupted because of its original source. // // e.g. I encountered the entry like the following. // "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami); ..." // This kind of entry is not able to be inserted via Android devices, but // possible if the source of the data is already corrupted. List<String> phoneNumberList = splitIfSeveralPhoneNumbersExist(phoneNumber); final List<String> phoneNumberList = splitAndTrimPhoneNumbers(phoneNumber); if (phoneNumberList.isEmpty()) { continue; } Loading @@ -670,7 +666,7 @@ public class VCardBuilder { phoneSet.add(actualPhoneNumber); appendTelLine(type, label, formattedPhoneNumber, isPrimary); } } } // for (String actualPhoneNumber : phoneNumberList) { } } } Loading @@ -682,15 +678,38 @@ public class VCardBuilder { return this; } private List<String> splitIfSeveralPhoneNumbersExist(final String phoneNumber) { List<String> phoneList = new ArrayList<String>(); /** * <p> * Splits a given string expressing phone numbers into several strings, and remove * unnecessary characters inside them. The size of a returned list becomes 1 when * no split is needed. * </p> * <p> * The given number "may" have several phone numbers when the contact entry is corrupted * because of its original source. * e.g. "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami)" * </p> * <p> * This kind of "phone numbers" will not be created with Android vCard implementation, * but we may encounter them if the source of the input data has already corrupted * implementation. * </p> * <p> * To handle this case, this method first splits its input into multiple parts * (e.g. "111-222-3333 (Miami)", "444-555-6666 (Broward", and 305653-6796 (Miami)") and * removes unnecessary strings like "(Miami)". * </p> * <p> * Do not call this method when trimming is inappropriate for its receivers. * </p> */ private List<String> splitAndTrimPhoneNumbers(final String phoneNumber) { final List<String> phoneList = new ArrayList<String>(); StringBuilder builder = new StringBuilder(); final int length = phoneNumber.length(); for (int i = 0; i < length; i++) { final char ch = phoneNumber.charAt(i); // TODO: add a test case for string with '+', and care the other possible issues // which may happen by ignoring non-digits other than '+'. if (Character.isDigit(ch) || ch == '+') { builder.append(ch); } else if ((ch == ';' || ch == '\n') && builder.length() > 0) { Loading
core/java/android/pim/vcard/VCardConfig.java +30 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package android.pim.vcard; import android.telephony.PhoneNumberUtils; import android.util.Log; import java.util.HashMap; Loading Loading @@ -190,6 +191,30 @@ public class VCardConfig { */ public static final int FLAG_REFRAIN_IMAGE_EXPORT = 0x02000000; /** * <P> * The flag indicating the vCard composer does touch nothing toward phone number Strings * but leave it as is. * </P> * <P> * The vCard specifications mention nothing toward phone numbers, while some devices * do (wrongly, but with innevitable reasons). * For example, there's a possibility Japanese mobile phones are expected to have * just numbers, hypens, plus, etc. but not usual alphabets, while US mobile phones * should get such characters. To make exported vCard simple for external parsers, * we have used {@link PhoneNumberUtils#formatNumber(String)} during export, and * removed unnecessary characters inside the number (e.g. "111-222-3333 (Miami)" * becomes "111-222-3333"). * Unfortunate side effect of that use was some control characters used in the other * areas may be badly affected by the formatting. * </P> * <P> * This flag disables that formatting, affecting both importer and exporter. * If the user is aware of some side effects due to the implicit formatting, use this flag. * </P> */ public static final int FLAG_REFRAIN_PHONE_NUMBER_FORMATTING = 0x02000000; //// The followings are VCard types available from importer/exporter. //// /** Loading Loading @@ -431,6 +456,10 @@ public class VCardConfig { return sJapaneseMobileTypeSet.contains(vcardType); } /* package */ static boolean refrainPhoneNumberFormatting(final int vcardType) { return ((vcardType & FLAG_REFRAIN_PHONE_NUMBER_FORMATTING) != 0); } public static boolean needsToConvertPhoneticString(final int vcardType) { return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0); } Loading
core/java/android/pim/vcard/VCardEntry.java +2 −3 Original line number Diff line number Diff line Loading @@ -488,7 +488,7 @@ public class VCardEntry { final StringBuilder builder = new StringBuilder(); final String trimed = data.trim(); final String formattedNumber; if (type == Phone.TYPE_PAGER) { if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) { formattedNumber = trimed; } else { final int length = trimed.length(); Loading @@ -500,8 +500,7 @@ public class VCardEntry { } // Use NANP in default when there's no information about locale. final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ? PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP); final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType); formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType); } PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary); Loading
core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java +10 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,16 @@ public class VCardExporterTests extends VCardTestsBase { testPhoneBasicCommon(V30); } public void testPhoneRefrainFormatting() { mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING); mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE) .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)") .put(Phone.TYPE, Phone.TYPE_HOME); mVerifier.addPropertyNodesVerifierElemWithEmptyName() .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)", new TypeSet("HOME")); } /** * Tests that vCard composer emits corresponding type param which we expect. */ Loading