diff --git a/res/values/e_arrays.xml b/res/values/e_arrays.xml new file mode 100644 index 0000000000000000000000000000000000000000..a38cce56ce220eb09b4fdd4a9b123da167ba3f12 --- /dev/null +++ b/res/values/e_arrays.xml @@ -0,0 +1,28 @@ + + + + + @string/menu_export_type_vcf_21 + @string/menu_export_type_vcf_30 + @string/menu_export_type_vcf_40 + + + + @string/menu_export_type_vcf_21_value + @string/menu_export_type_vcf_30_value + @string/menu_export_type_vcf_40_value + + diff --git a/res/values/strings.xml b/res/values/strings.xml index faa1d96e130018c95cb3cb6d6953321155b75595..a1a5dcd808f9a6c5fb8a9dbb45218b2d31c5e313 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1551,4 +1551,13 @@ No + + Export vCard version + VCF 2.1 + VCF 3.0 + VCF 4.0 + v21_generic + v30_generic + v40_generic + \ No newline at end of file diff --git a/res/xml/preference_display_options.xml b/res/xml/preference_display_options.xml index c969cd24f15115b3df9de57909a6b9c05f452526..9f30a8fdcc7d78e20901d40e2652852fe804ac9c 100644 --- a/res/xml/preference_display_options.xml +++ b/res/xml/preference_display_options.xml @@ -65,6 +65,14 @@ android:key="export" android:title="@string/menu_export"/> + + sVCardTypeMap = new HashMap<>(); + sVCardTypeMap.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC); + sVCardTypeMap.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC); + sVCardTypeMap.put(VCARD_TYPE_V40_GENERIC_STR, VCARD_TYPE_V40_GENERIC); + + final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences( + mService.getApplicationContext()); + final String defVcfType = pref.getString(KEY_EXPORT_TYPE, + VCARD_TYPE_V40_GENERIC_STR); + final int vcardType = sVCardTypeMap.get(defVcfType); composer = new VCardComposer(mService, vcardType, true); diff --git a/src/com/android/contacts/vcard/ImportProcessor.java b/src/com/android/contacts/vcard/ImportProcessor.java index c6fcccb8c2c9f6e63fa3afb6474c57a544774b61..bdeb35312dd7f9e3716d595e8a2013eb6380fe4a 100644 --- a/src/com/android/contacts/vcard/ImportProcessor.java +++ b/src/com/android/contacts/vcard/ImportProcessor.java @@ -30,6 +30,7 @@ import com.android.vcard.VCardInterpreter; import com.android.vcard.VCardParser; import com.android.vcard.VCardParser_V21; import com.android.vcard.VCardParser_V30; +import com.android.vcard.VCardParser_V40; import com.android.vcard.exception.VCardException; import com.android.vcard.exception.VCardNotSupportedException; import com.android.vcard.exception.VCardVersionException; @@ -135,7 +136,8 @@ public class ImportProcessor extends ProcessorBase implements VCardEntryHandler */ possibleVCardVersions = new int[] { ImportVCardActivity.VCARD_VERSION_V21, - ImportVCardActivity.VCARD_VERSION_V30 + ImportVCardActivity.VCARD_VERSION_V30, + ImportVCardActivity.VCARD_VERSION_V40 }; } else { possibleVCardVersions = new int[] { @@ -231,9 +233,10 @@ public class ImportProcessor extends ProcessorBase implements VCardEntryHandler // In the worst case, a user may call cancel() just before creating // mVCardParser. synchronized (this) { - mVCardParser = (vcardVersion == ImportVCardActivity.VCARD_VERSION_V30 ? - new VCardParser_V30(vcardType) : - new VCardParser_V21(vcardType)); + VCardParser useOldVcardParser = (vcardVersion == ImportVCardActivity.VCARD_VERSION_V30 ? + new VCardParser_V30(vcardType) : new VCardParser_V21(vcardType)); + mVCardParser = (vcardVersion == ImportVCardActivity.VCARD_VERSION_V40 ? + new VCardParser_V40(vcardType) : useOldVcardParser); if (isCancelled()) { Log.i(LOG_TAG, "ImportProcessor already recieves cancel request, so " + "send cancel request to vCard parser too."); diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java index 38367c40f9b55a0118c140665cb375931745b2da..d89f1fdcd5f5d96e9c8fd7d68f91ba11cf63d356 100644 --- a/src/com/android/contacts/vcard/ImportVCardActivity.java +++ b/src/com/android/contacts/vcard/ImportVCardActivity.java @@ -49,6 +49,7 @@ import com.android.vcard.VCardEntryCounter; import com.android.vcard.VCardParser; import com.android.vcard.VCardParser_V21; import com.android.vcard.VCardParser_V30; +import com.android.vcard.VCardParser_V40; import com.android.vcard.VCardSourceDetector; import com.android.vcard.exception.VCardException; import com.android.vcard.exception.VCardNestedException; @@ -83,6 +84,7 @@ public class ImportVCardActivity extends Activity implements ImportVCardDialogFr /* package */ final static int VCARD_VERSION_AUTO_DETECT = 0; /* package */ final static int VCARD_VERSION_V21 = 1; /* package */ final static int VCARD_VERSION_V30 = 2; + /* package */ final static int VCARD_VERSION_V40 = 3; private static final int REQUEST_OPEN_DOCUMENT = 100; @@ -321,6 +323,7 @@ public class ImportVCardActivity extends Activity implements ImportVCardDialogFr int vcardVersion = VCARD_VERSION_V21; try { boolean shouldUseV30 = false; + boolean shouldUseV40 = false; InputStream is; if (data != null) { is = new ByteArrayInputStream(data); @@ -354,7 +357,28 @@ public class ImportVCardActivity extends Activity implements ImportVCardDialogFr mVCardParser.addInterpreter(detector); mVCardParser.parse(is); } catch (VCardVersionException e2) { - throw new VCardException("vCard with unspported version."); + try { + is.close(); + } catch (IOException e) { + + } + + shouldUseV40 = true; + if (data != null) { + is = new ByteArrayInputStream(data); + } else { + is = resolver.openInputStream(localDataUri); + } + mVCardParser = new VCardParser_V40(); + try { + counter = new VCardEntryCounter(); + detector = new VCardSourceDetector(); + mVCardParser.addInterpreter(counter); + mVCardParser.addInterpreter(detector); + mVCardParser.parse(is); + } catch (VCardVersionException e3) { + throw new VCardException("vCard with unspported version."); + } } } finally { if (is != null) { @@ -365,7 +389,8 @@ public class ImportVCardActivity extends Activity implements ImportVCardDialogFr } } - vcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21; + int useOldvcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21; + vcardVersion = shouldUseV40 ? VCARD_VERSION_V40 : useOldvcardVersion; } catch (VCardNestedException e) { Log.w(LOG_TAG, "Nested Exception is found (it may be false-positive)."); // Go through without throwing the Exception, as we may be able to detect the