Contacts: add support for importing VCF v4
Change-Id: I07246d624b277417ed60f67c4b50e99cb9761111
diff --git a/src/com/android/contacts/vcard/ImportProcessor.java b/src/com/android/contacts/vcard/ImportProcessor.java
index c6fcccb..9471fd9 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.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 @@
*/
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,16 @@
// 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));
+ switch (vcardVersion) {
+ case ImportVCardActivity.VCARD_VERSION_V40:
+ mVCardParser = new VCardParser_V40(vcardType);
+ break;
+ case ImportVCardActivity.VCARD_VERSION_V30:
+ mVCardParser = new VCardParser_V30(vcardType);
+ break;
+ default:
+ mVCardParser = new VCardParser_V21(vcardType);
+ }
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 3eb7bdb..7ff6320 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.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 @@
/* 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 @@
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 @@
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,13 @@
}
}
- vcardVersion = shouldUseV30 ? VCARD_VERSION_V30 : VCARD_VERSION_V21;
+ if (shouldUseV40) {
+ vcardVersion = VCARD_VERSION_V40;
+ } else if (shouldUseV30) {
+ vcardVersion = VCARD_VERSION_V30;
+ } else {
+ vcardVersion = VCARD_VERSION_V21;
+ }
} 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