VCardEntry.java revision 88d0f1ef715f2e1209eba5d175b1b71c556fa8b0
14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/*
24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project
34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * you may not use this file except in compliance with the License.
64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * You may obtain a copy of the License at
74199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
84199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
94199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * See the License for the specific language governing permissions and
144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * limitations under the License.
154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapackage com.android.vcard;
174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.accounts.Account;
194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderOperation;
204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderResult;
214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentResolver;
224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.OperationApplicationException;
234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.net.Uri;
244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.os.RemoteException;
254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Email;
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Im;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Nickname;
314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Note;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Organization;
334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Phone;
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Photo;
3588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Website;
3988d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Contacts;
4088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Data;
4188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.RawContacts;
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.telephony.PhoneNumberUtils;
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.text.TextUtils;
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log;
454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays;
484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collection;
494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collections;
504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashMap;
514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet;
524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List;
534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Map;
544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/**
564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This class bridges between data structure of Contact app and VCard data.
574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapublic class VCardEntry {
594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final String LOG_TAG = "VCardEntry";
604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final static int DEFAULT_ORGANIZATION_TYPE = Organization.TYPE_WORK;
624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final Map<String, Integer> sImMap = new HashMap<String, Integer>();
644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    static {
664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_AIM, Im.PROTOCOL_AIM);
674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_MSN, Im.PROTOCOL_MSN);
684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_YAHOO, Im.PROTOCOL_YAHOO);
694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_ICQ, Im.PROTOCOL_ICQ);
704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER);
714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE);
724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK);
734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Im.PROTOCOL_GOOGLE_TALK);
754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhoneData {
784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // isPrimary is (not final but) changable, only when there's no appropriate one existing
824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // in the original VCard.
834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhoneData(int type, String data, String label, boolean isPrimary) {
854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhoneData)) {
944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhoneData phoneData = (PhoneData)obj;
974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == phoneData.type && data.equals(phoneData.data) &&
984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(phoneData.label) && isPrimary == phoneData.isPrimary);
994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class EmailData {
1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Used only when TYPE is TYPE_CUSTOM.
1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public EmailData(int type, String data, String label, boolean isPrimary) {
1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof EmailData)) {
1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            EmailData emailData = (EmailData)obj;
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == emailData.type && data.equals(emailData.data) &&
1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(emailData.label) && isPrimary == emailData.isPrimary);
1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PostalData {
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Determined by vCard specification.
1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // - PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country Name
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final int ADDR_MAX_DATA_SIZE = 7;
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private final String[] dataArray;
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String pobox;
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String extendedAddress;
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String street;
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String localty;
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String region;
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String postalCode;
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String country;
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PostalData(final int type, final List<String> propValueList,
1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String label, boolean isPrimary) {
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            dataArray = new String[ADDR_MAX_DATA_SIZE];
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int size = propValueList.size();
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (size > ADDR_MAX_DATA_SIZE) {
1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                size = ADDR_MAX_DATA_SIZE;
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // adr-value = 0*6(text-value ";") text-value
1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; PO Box, Extended Address, Street, Locality, Region, Postal
1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; Code, Country Name
1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //
1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Use Iterator assuming List may be LinkedList, though actually it is
1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // always ArrayList in the current implementation.
1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String addressElement : propValueList) {
1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i] = addressElement;
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (++i >= size) {
1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            while (i < ADDR_MAX_DATA_SIZE) {
1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i++] = null;
1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.pobox = dataArray[0];
1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.extendedAddress = dataArray[1];
1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.street = dataArray[2];
1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.localty = dataArray[3];
1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.region = dataArray[4];
1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.postalCode = dataArray[5];
1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.country = dataArray[6];
1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PostalData)) {
1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final PostalData postalData = (PostalData)obj;
1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (Arrays.equals(dataArray, postalData.dataArray) &&
1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (type == postalData.type &&
2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            (type == StructuredPostal.TYPE_CUSTOM ?
2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                                    (label == postalData.label) : true)) &&
2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == postalData.isPrimary));
2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedAddress(final int vcardType) {
2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean empty = true;
2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (VCardConfig.isJapaneseDevice(vcardType)) {
2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In Japan, the order is reversed.
2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = ADDR_MAX_DATA_SIZE - 1; i >= 0; i--) {
2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 0; i < ADDR_MAX_DATA_SIZE; i++) {
2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString().trim();
2364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, label: %s, isPrimary: %s",
2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, label, isPrimary);
2424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class OrganizationData {
2464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
2474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // non-final is Intentional: we may change the values since this info is separated into
2484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // two parts in vCard: "ORG" + "TITLE", and we have to cope with each field in
2494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // different timing.
2504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String companyName;
2514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String departmentName;
2524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String titleName;
2534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        public final String phoneticName;  // We won't have this in "TITLE" property.
2544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
2554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public OrganizationData(int type,
2574560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String companyName,
2584560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String departmentName,
2594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String titleName,
2604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String phoneticName,
2614560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final boolean isPrimary) {
2624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
2634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.companyName = companyName;
2644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.departmentName = departmentName;
2654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.titleName = titleName;
2664560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            this.phoneticName = phoneticName;
2674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
2684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
2724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof OrganizationData)) {
2734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
2744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            OrganizationData organization = (OrganizationData)obj;
2764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == organization.type &&
2774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(companyName, organization.companyName) &&
2784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(departmentName, organization.departmentName) &&
2794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(titleName, organization.titleName) &&
2804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    isPrimary == organization.isPrimary);
2814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedString() {
2844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
2854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(companyName)) {
2864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(companyName);
2874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(departmentName)) {
2904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
2914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
2924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(departmentName);
2944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(titleName)) {
2974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
2984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
2994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
3004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(titleName);
3014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
3044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, company: %s, department: %s, title: %s, isPrimary: %s",
3104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, companyName, departmentName, titleName, isPrimary);
3114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class ImData {
3154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int protocol;
3164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String customProtocol;
3174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
3194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public ImData(final int protocol, final String customProtocol, final int type,
3224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String data, final boolean isPrimary) {
3234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.protocol = protocol;
3244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.customProtocol = customProtocol;
3254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
3274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof ImData)) {
3334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ImData imData = (ImData)obj;
3364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == imData.type && protocol == imData.protocol
3374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (customProtocol != null ? customProtocol.equals(imData.customProtocol) :
3384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        (imData.customProtocol == null))
3394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (data != null ? data.equals(imData.data) : (imData.data == null))
3404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && isPrimary == imData.isPrimary);
3414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s",
3474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, protocol, customProtocol, data, isPrimary);
3484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhotoData {
3524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final String FORMAT_FLASH = "SWF";
3534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String formatName;  // used when type is not defined in ContactsContract.
3554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final byte[] photoBytes;
3564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhotoData(int type, String formatName, byte[] photoBytes, boolean isPrimary) {
3594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.formatName = formatName;
3614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.photoBytes = photoBytes;
3624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhotoData)) {
3684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhotoData photoData = (PhotoData)obj;
3714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == photoData.type &&
3724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (formatName == null ? (photoData.formatName == null) :
3734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName.equals(photoData.formatName)) &&
3744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (Arrays.equals(photoBytes, photoData.photoBytes)) &&
3754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == photoData.isPrimary));
3764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, format: %s: size: %d, isPrimary: %s",
3814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, formatName, photoBytes.length, isPrimary);
3824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /* package */ static class Property {
3864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private String mPropertyName;
3874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private Map<String, Collection<String>> mParameterMap =
3884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new HashMap<String, Collection<String>>();
3894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private List<String> mPropertyValueList = new ArrayList<String>();
3904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private byte[] mPropertyBytes;
3914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyName(final String propertyName) {
3934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = propertyName;
3944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void addParameter(final String paramName, final String paramValue) {
3974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> values;
3984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!mParameterMap.containsKey(paramName)) {
3994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (paramName.equals("TYPE")) {
4004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new HashSet<String>();
4014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
4024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new ArrayList<String>();
4034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
4044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mParameterMap.put(paramName, values);
4054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
4064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                values = mParameterMap.get(paramName);
4074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
4084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            values.add(paramValue);
4094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void addToPropertyValueList(final String propertyValue) {
4124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.add(propertyValue);
4134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyBytes(final byte[] propertyBytes) {
4164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = propertyBytes;
4174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final Collection<String> getParameters(String type) {
4204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mParameterMap.get(type);
4214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final List<String> getPropertyValueList() {
4244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mPropertyValueList;
4254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void clear() {
4284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = null;
4294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mParameterMap.clear();
4304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.clear();
4314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = null;
4324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4354560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // TODO(dmiyakawa): vCard 4.0 logically has multiple formatted names and we need to
4364560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // select the most preferable one using PREF parameter.
4374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    //
4384560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // e.g. (based on rev.13)
4394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=1:John M. Doe
4404560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=2:John Doe
4414560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=3;John
4424560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
4434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFamilyName;
4444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mGivenName;
4454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mMiddleName;
4464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPrefix;
4474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mSuffix;
4484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Used only when no family nor given name is found.
4504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFormattedName;
4514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFamilyName;
4534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticGivenName;
4544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticMiddleName;
4554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFullName;
4574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNickNameList;
4594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mDisplayName;
4614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mBirthday;
463c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa    private String mAnniversary;
4644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNoteList;
4664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhoneData> mPhoneList;
4674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<EmailData> mEmailList;
4684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PostalData> mPostalList;
4694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<OrganizationData> mOrganizationList;
4704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<ImData> mImList;
4714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhotoData> mPhotoList;
4724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mWebsiteList;
47388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa    private List<String> mSipList;
4744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<List<String>> mAndroidCustomPropertyList;
4754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final int mVCardType;
4774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final Account mAccount;
4784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry() {
4804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(VCardConfig.VCARD_TYPE_V21_GENERIC);
4814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType) {
4844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(vcardType, null);
4854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType, Account account) {
4884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mVCardType = vcardType;
4894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAccount = account;
4904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhone(int type, String data, String label, boolean isPrimary) {
4934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList == null) {
4944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneList = new ArrayList<PhoneData>();
4954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final StringBuilder builder = new StringBuilder();
4974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String trimed = data.trim();
4984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String formattedNumber;
4994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) {
5004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            formattedNumber = trimed;
5014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
5024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int length = trimed.length();
5034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 0; i < length; i++) {
5044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                char ch = trimed.charAt(i);
5054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
5064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(ch);
5074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
5084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
5094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType);
5114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType);
5124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary);
5144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhoneList.add(phoneData);
5154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNickName(final String nickName) {
5184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList == null) {
5194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNickNameList = new ArrayList<String>();
5204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNickNameList.add(nickName);
5224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addEmail(int type, String data, String label, boolean isPrimary){
5254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList == null) {
5264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mEmailList = new ArrayList<EmailData>();
5274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mEmailList.add(new EmailData(type, data, label, isPrimary));
5294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPostal(int type, List<String> propValueList, String label, boolean isPrimary){
5324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList == null) {
5334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPostalList = new ArrayList<PostalData>(0);
5344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPostalList.add(new PostalData(type, propValueList, label, isPrimary));
5364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
5394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * Should be called via {@link #handleOrgValue(int, List, Map, boolean) or
5404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link #handleTitleValue(String)}.
5414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
5424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNewOrganization(int type, final String companyName,
5434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String departmentName,
5444560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String titleName,
5454560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String phoneticName,
5464560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final boolean isPrimary) {
5474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
5484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mOrganizationList = new ArrayList<OrganizationData>();
5494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mOrganizationList.add(new OrganizationData(type, companyName,
5514560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                departmentName, titleName, phoneticName, isPrimary));
5524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final List<String> sEmptyList =
5554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collections.unmodifiableList(new ArrayList<String>(0));
5564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5574560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private String buildSinglePhoneticNameFromSortAsParam(Map<String, Collection<String>> paramMap) {
5584560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
5594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
5604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
5614560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
5624560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
5634560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
5644560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
5654560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
5664560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
5674560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
5684560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            for (final String elem : sortNames) {
5694560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                builder.append(elem);
5704560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
5714560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return builder.toString();
5724560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        } else {
5734560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return null;
5744560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
5754560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
5764560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
5774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
5784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "ORG" related values to the appropriate data. If there's more than one
5794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} objects, this input data are attached to the last one which
5804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * does not have valid values (not including empty but only null). If there's no
5814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} object, a new {@link OrganizationData} is created,
5824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * whose title is set to null.
5834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
5844560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleOrgValue(final int type, List<String> orgList,
5854560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap, boolean isPrimary) {
5864560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final String phoneticName = buildSinglePhoneticNameFromSortAsParam(paramMap);
5874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (orgList == null) {
5884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            orgList = sEmptyList;
5894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String companyName;
5914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String departmentName;
5924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = orgList.size();
5934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
5944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 0: {
5954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = "";
5964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
5974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
5984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
5994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 1: {
6004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
6024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
6034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: {  // More than 1.
6054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We're not sure which is the correct string for department.
6074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In order to keep all the data, concatinate the rest of elements.
6084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                StringBuilder builder = new StringBuilder();
6094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 1; i < size; i++) {
6104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i > 1) {
6114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(' ');
6124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
6134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(orgList.get(i));
6144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
6154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = builder.toString();
6164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" title which may be
6204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleTitleValue().
6214560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
6224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
6234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
6254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Not use TextUtils.isEmpty() since ORG was set but the elements might be empty.
6264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // e.g. "ORG;PREF:;" -> Both companyName and departmentName become empty but not null.
6274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.companyName == null &&
6284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    organizationData.departmentName == null) {
6294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Probably the "TITLE" property comes before the "ORG" property via
6304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // handleTitleLine().
6314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.companyName = companyName;
6324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.departmentName = departmentName;
6334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.isPrimary = isPrimary;
6344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
6354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No OrganizatioData is available. Create another one, with "null" title, which may be
6384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleTitleValue().
6394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
6404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
6434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "title" value to the appropriate data. If there's more than one
6444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData objects, this input is attached to the last one which does not
6454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * have valid title value (not including empty but only null). If there's no
6464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData object, a new OrganizationData is created, whose company name is
6474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * set to null.
6484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
6494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleTitleValue(final String title) {
6504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" other info, which may be
6524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleOrgValue().
6534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
6544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
6554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
6574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.titleName == null) {
6584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.titleName = title;
6594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
6604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No Organization is available. Create another one, with "null" other info, which may be
6634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleOrgValue().
6644560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
6654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addIm(int protocol, String customProtocol, int type,
6684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String propValue, boolean isPrimary) {
6694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList == null) {
6704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mImList = new ArrayList<ImData>();
6714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary));
6734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNote(final String note) {
6764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList == null) {
6774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNoteList = new ArrayList<String>(1);
6784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNoteList.add(note);
6804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhotoBytes(String formatName, byte[] photoBytes, boolean isPrimary) {
6834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList == null) {
6844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhotoList = new ArrayList<PhotoData>(1);
6854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final PhotoData photoData = new PhotoData(0, null, photoBytes, isPrimary);
6874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhotoList.add(photoData);
6884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6904560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    /**
6914560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * Tries to extract paramMap, constructs SORT-AS parameter values, and store them in
6924560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * appropriate phonetic name variables.
6934560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     *
6944560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * This method does not care the vCard version. Even when we have SORT-AS parameters in
6954560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * invalid versions (i.e. 2.1 and 3.0), we scilently accept them so that we won't drop
6964560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * meaningful information. If we had this parameter in the N field of vCard 3.0, and
6974560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * the contact data also have SORT-STRING, we will prefer SORT-STRING, since it is
6984560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * regitimate property to be understood.
6994560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     */
7004560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void tryHandleSortAsName(final Map<String, Collection<String>> paramMap) {
7014560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (VCardConfig.isVersion30(mVCardType) &&
7024560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                !(TextUtils.isEmpty(mPhoneticFamilyName) &&
7034560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticMiddleName) &&
7044560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticGivenName))) {
7054560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return;
7064560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7074560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7084560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
7094560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
7104560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
7114560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
7124560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
7134560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7144560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
7154560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
7164560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
7174560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            int size = sortNames.size();
7184560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (size > 3) {
7194560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                size = 3;
7204560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7214560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            switch (size) {
7224560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 3: mPhoneticMiddleName = sortNames.get(2); //$FALL-THROUGH$
7234560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 2: mPhoneticGivenName = sortNames.get(1); //$FALL-THROUGH$
7244560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            default: mPhoneticFamilyName = sortNames.get(0); break;
7254560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7264560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7274560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
7284560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
7304560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleNProperty(final List<String> paramValues,
7314560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap) {
7324560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // in vCard 4.0, SORT-AS parameter is available.
7334560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        tryHandleSortAsName(paramMap);
7344560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
7364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
7374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (paramValues == null || (size = paramValues.size()) < 1) {
7384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 5) {
7414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 5;
7424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
7454560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // Fall-through.
7464560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 5: mSuffix = paramValues.get(4);
7474560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 4: mPrefix = paramValues.get(3);
7484560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 3: mMiddleName = paramValues.get(2);
7494560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 2: mGivenName = paramValues.get(1);
7504560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        default: mFamilyName = paramValues.get(0);
7514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
7554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Note: Some Japanese mobile phones use this field for phonetic name,
7564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       since vCard 2.1 does not have "SORT-STRING" type.
7574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Also, in some cases, the field has some ';'s in it.
7584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Assume the ';' means the same meaning in N property
7594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
7604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
7614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handlePhoneticNameFromSound(List<String> elems) {
7624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
7634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticMiddleName) &&
7644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
7654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
7664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Ignore "SOUND;X-IRMC-N".
7674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
7714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems == null || (size = elems.size()) < 1) {
7724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Assume that the order is "Family, Given, Middle".
7764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // This is not from specification but mere assumption. Some Japanese phones use this order.
7774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 3) {
7784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 3;
7794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems.get(0).length() > 0) {
7824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean onlyFirstElemIsNonEmpty = true;
7834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 1; i < size; i++) {
7844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (elems.get(i).length() > 0) {
7854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    onlyFirstElemIsNonEmpty = false;
7864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
7874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
7884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
7894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (onlyFirstElemIsNonEmpty) {
7904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String[] namesArray = elems.get(0).split(" ");
7914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final int nameArrayLength = namesArray.length;
7924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (nameArrayLength == 3) {
7934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Middle Given".
7944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
7954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticMiddleName = namesArray[1];
7964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[2];
7974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (nameArrayLength == 2) {
7984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Given" based on the Japanese mobile
7994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // phones' preference.
8004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
8014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[1];
8024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
8034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFullName = elems.get(0);
8044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
8064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
8104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // fallthrough
8114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 3: mPhoneticMiddleName = elems.get(2);
8124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 2: mPhoneticGivenName = elems.get(1);
8134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: mPhoneticFamilyName = elems.get(0);
8144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
8164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void addProperty(final Property property) {
8184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propName = property.mPropertyName;
8194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final Map<String, Collection<String>> paramMap = property.mParameterMap;
8204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final List<String> propValueList = property.mPropertyValueList;
8214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        byte[] propBytes = property.mPropertyBytes;
8224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propValueList.size() == 0) {
8244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propValue = listToString(propValueList).trim();
8274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propName.equals(VCardConstants.PROPERTY_VERSION)) {
8294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard version. Ignore this.
8304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_FN)) {
8314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
8324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NAME) && mFormattedName == null) {
8334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Only in vCard 3.0. Use this if FN, which must exist in vCard 3.0 but may not
8344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // actually exist in the real vCard data, does not exist.
8354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
8364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_N)) {
8374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleNProperty(propValueList, paramMap);
8384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SORT_STRING)) {
8394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = propValue;
8404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NICKNAME) ||
8414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.ImportOnly.PROPERTY_X_NICKNAME)) {
8424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNickName(propValue);
8434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SOUND)) {
8444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null
8464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && typeCollection.contains(VCardConstants.PARAM_TYPE_X_IRMC_N)) {
8474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // As of 2009-10-08, Parser side does not split a property value into separated
8484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // values using ';' (in other words, propValueList.size() == 1),
8494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // which is correct behavior from the view of vCard 2.1.
8504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // But we want it to be separated, so do the separation here.
8514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final List<String> phoneticNameList =
8524560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        VCardUtils.constructListFromValue(propValue, mVCardType);
8534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                handlePhoneticNameFromSound(phoneticNameList);
8544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
8554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Ignore this field since Android cannot understand what it is.
8564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ADR)) {
8584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean valuesAreAllEmpty = true;
8594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String value : propValueList) {
8604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (value.length() > 0) {
8614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    valuesAreAllEmpty = false;
8624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
8634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (valuesAreAllEmpty) {
8664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
8674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
8704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = "";
8714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
8724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
8744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
8754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    typeString = typeString.toUpperCase();
8764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
8774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
8784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
8794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_HOME;
8804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
8814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK) ||
8824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equalsIgnoreCase(VCardConstants.PARAM_EXTRA_TYPE_COMPANY)) {
8834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // "COMPANY" seems emitted by Windows Mobile, which is not
8844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // specifically supported by vCard 2.1. We assume this is same
8854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // as "WORK".
8864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_WORK;
8874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
8884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_ADR_TYPE_PARCEL) ||
8894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_DOM) ||
8904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_INTL)) {
8914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // We do not have any appropriate way to store this information.
8924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {
8934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.startsWith("X-") && type < 0) {
8944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString = typeString.substring(2);
8954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
8964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
8974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // emit non-standard types. We do not handle their values now.
8984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_CUSTOM;
8994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = typeString;
9004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // We use "HOME" as default
9044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
9054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = StructuredPostal.TYPE_HOME;
9064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPostal(type, propValueList, label, isPrimary);
9094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_EMAIL)) {
9104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
9114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = null;
9124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
9134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
9154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
9164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    typeString = typeString.toUpperCase();
9174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
9184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
9194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
9204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_HOME;
9214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK)) {
9224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_WORK;
9234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_CELL)) {
9244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_MOBILE;
9254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {
9264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.startsWith("X-") && type < 0) {
9274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString = typeString.substring(2);
9284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
9294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // vCard 3.0 allows iana-token.
9304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // We may have INTERNET (specified in vCard spec),
9314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // SCHOOL, etc.
9324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_CUSTOM;
9334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = typeString;
9344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
9384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Email.TYPE_OTHER;
9394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addEmail(type, propValue, label, isPrimary);
9414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ORG)) {
9424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard specification does not specify other types.
9434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Organization.TYPE_WORK;
9444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
9454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
9474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
9484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
9494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
9504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleOrgValue(type, propValueList, paramMap, isPrimary);
9544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TITLE)) {
9554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleTitleValue(propValue);
9564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ROLE)) {
9574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This conflicts with TITLE. Ignore for now...
9584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // handleTitleValue(propValue);
9594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_PHOTO) ||
9604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.PROPERTY_LOGO)) {
9614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> paramMapValue = paramMap.get("VALUE");
9624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (paramMapValue != null && paramMapValue.contains("URL")) {
9634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Currently we do not have appropriate example for testing this case.
9644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
9654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final Collection<String> typeCollection = paramMap.get("TYPE");
9664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                String formatName = null;
9674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                boolean isPrimary = false;
9684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (typeCollection != null) {
9694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    for (String typeValue : typeCollection) {
9704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (VCardConstants.PARAM_TYPE_PREF.equals(typeValue)) {
9714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            isPrimary = true;
9724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (formatName == null){
9734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName = typeValue;
9744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
9754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                addPhotoBytes(formatName, propBytes, isPrimary);
9784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TEL)) {
9804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Object typeObject =
9824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                VCardUtils.getPhoneTypeFromStrings(typeCollection, propValue);
9834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type;
9844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String label;
9854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeObject instanceof Integer) {
9864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = (Integer)typeObject;
9874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = null;
9884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
9894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Phone.TYPE_CUSTOM;
9904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = typeObject.toString();
9914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
9944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null && typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
9954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
9964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
9974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
9984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPhone(type, propValue, label, isPrimary);
10004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_SKYPE_PSTNNUMBER)) {
10014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // The phone number available via Skype.
10024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Phone.TYPE_OTHER;
10044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
10054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null && typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
10064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
10074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
10094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPhone(type, propValue, null, isPrimary);
10114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (sImMap.containsKey(propName)) {
10124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int protocol = sImMap.get(propName);
10134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
10144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
10154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
10174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
10184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
10194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
10204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (type < 0) {
10214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_HOME)) {
10224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_HOME;
10234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_WORK)) {
10244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_WORK;
10254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
10264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
10274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
10284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
103006ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                type = Im.TYPE_HOME;
10314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addIm(protocol, null, type, propValue, isPrimary);
10334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NOTE)) {
10344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNote(propValue);
10354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_URL)) {
10364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (mWebsiteList == null) {
10374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mWebsiteList = new ArrayList<String>(1);
10384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mWebsiteList.add(propValue);
10404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_BDAY)) {
10414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mBirthday = propValue;
1042c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ANNIVERSARY)) {
1043c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            mAnniversary = propValue;
10444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_FIRST_NAME)) {
10454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticGivenName = propValue;
10464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) {
10474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticMiddleName = propValue;
10484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_LAST_NAME)) {
10494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFamilyName = propValue;
105088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_IMPP)) {
105188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            // See also RFC 4770 (for vCard 3.0)
105288d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            if (propValue.startsWith("sip:") && propValue.length() > 4) {
105388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                if (mSipList == null) {
105488d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                    mSipList = new ArrayList<String>();
105588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                }
105688d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                mSipList.add(propValue.substring(4));
105788d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
10584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_ANDROID_CUSTOM)) {
10594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final List<String> customPropertyList =
10604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                VCardUtils.constructListFromValue(propValue, mVCardType);
10614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleAndroidCustomProperty(customPropertyList);
10624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
10634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
10644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
10654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
10664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleAndroidCustomProperty(final List<String> customPropertyList) {
10674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList == null) {
10684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mAndroidCustomPropertyList = new ArrayList<List<String>>();
10694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
10704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAndroidCustomPropertyList.add(customPropertyList);
10714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
10724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
10734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
10744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Construct the display name. The constructed data must not be null.
10754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
10764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void constructDisplayName() {
10774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // FullName (created via "FN" or "NAME" field) is prefered.
10784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mFormattedName)) {
10794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mFormattedName;
10804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
10814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
10824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
10834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
10844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
10854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
10864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName, mPhoneticMiddleName, mPhoneticGivenName);
10874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mEmailList != null && mEmailList.size() > 0) {
10884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mEmailList.get(0).data;
10894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPhoneList != null && mPhoneList.size() > 0) {
10904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPhoneList.get(0).data;
10914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPostalList != null && mPostalList.size() > 0) {
10924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
10934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
10944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mOrganizationList.get(0).getFormattedString();
10954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
10964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
10974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
10984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = "";
10994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
11034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Consolidate several fielsds (like mName) using name candidates,
11044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
11054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void consolidateFields() {
11064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        constructDisplayName();
11074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneticFullName != null) {
11094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = mPhoneticFullName.trim();
11104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public Uri pushIntoContentResolver(ContentResolver resolver) {
11144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ArrayList<ContentProviderOperation> operationList =
11154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new ArrayList<ContentProviderOperation>();
11164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // After applying the batch the first result's Uri is returned so it is important that
11174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // the RawContact is the first operation that gets inserted into the list
11184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ContentProviderOperation.Builder builder =
11194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
11204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        String myGroupsId = null;
11214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAccount != null) {
11224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, mAccount.name);
11234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
11244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
11254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, null);
11264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, null);
11274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        operationList.add(builder.build());
11294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!nameFieldsAreEmpty()) {
11314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
11324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
11334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
11344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.GIVEN_NAME, mGivenName);
11364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.FAMILY_NAME, mFamilyName);
11374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.MIDDLE_NAME, mMiddleName);
11384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.PREFIX, mPrefix);
11394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.SUFFIX, mSuffix);
11404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(TextUtils.isEmpty(mPhoneticGivenName)
11424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticFamilyName)
11434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticMiddleName))) {
11444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticGivenName);
11454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, mPhoneticFamilyName);
11464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_MIDDLE_NAME, mPhoneticMiddleName);
11474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (!TextUtils.isEmpty(mPhoneticFullName)) {
11484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticFullName);
11494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.DISPLAY_NAME, getDisplayName());
11524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
11534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList != null && mNickNameList.size() > 0) {
11564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String nickName : mNickNameList) {
11574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
11584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Nickname.RAW_CONTACT_ID, 0);
11594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
11604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
11614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.NAME, nickName);
11624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
11634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList != null) {
11674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhoneData phoneData : mPhoneList) {
11684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
11694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
11704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
11714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.TYPE, phoneData.type);
11734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.type == Phone.TYPE_CUSTOM) {
11744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.LABEL, phoneData.label);
11754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.NUMBER, phoneData.data);
11774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.isPrimary) {
11784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.IS_PRIMARY, 1);
11794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
11814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList != null) {
11854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (OrganizationData organizationData : mOrganizationList) {
11864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
11874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Organization.RAW_CONTACT_ID, 0);
11884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
11894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Organization.TYPE, organizationData.type);
11904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.companyName != null) {
11914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.COMPANY, organizationData.companyName);
11924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.departmentName != null) {
11944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.DEPARTMENT, organizationData.departmentName);
11954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.titleName != null) {
11974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.TITLE, organizationData.titleName);
11984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11994560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                if (organizationData.phoneticName != null) {
12004560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    builder.withValue(Organization.PHONETIC_NAME, organizationData.phoneticName);
12014560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                }
12024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.isPrimary) {
12034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.IS_PRIMARY, 1);
12044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList != null) {
12104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (EmailData emailData : mEmailList) {
12114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
12134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
12144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.TYPE, emailData.type);
12164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.type == Email.TYPE_CUSTOM) {
12174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Email.LABEL, emailData.label);
12184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.DATA, emailData.data);
12204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.isPrimary) {
12214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
12224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList != null) {
12284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PostalData postalData : mPostalList) {
12294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                VCardUtils.insertStructuredPostalDataUsingContactsStruct(
12314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        mVCardType, builder, postalData);
12324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList != null) {
12374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (ImData imData : mImList) {
12384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Im.RAW_CONTACT_ID, 0);
12404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
12414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.TYPE, imData.type);
12424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.PROTOCOL, imData.protocol);
124306ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                builder.withValue(Im.DATA, imData.data);
12444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.protocol == Im.PROTOCOL_CUSTOM) {
12454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol);
12464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.isPrimary) {
12484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
12494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
125006ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                operationList.add(builder.build());
12514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList != null) {
12554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String note : mNoteList) {
12564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Note.RAW_CONTACT_ID, 0);
12584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE);
12594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Note.NOTE, note);
12604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList != null) {
12654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhotoData photoData : mPhotoList) {
12664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Photo.RAW_CONTACT_ID, 0);
12684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
12694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Photo.PHOTO, photoData.photoBytes);
12704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (photoData.isPrimary) {
12714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Photo.IS_PRIMARY, 1);
12724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mWebsiteList != null) {
12784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String website : mWebsiteList) {
12794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Website.RAW_CONTACT_ID, 0);
12814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE);
12824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.URL, website);
12834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // There's no information about the type of URL in vCard.
12844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We use TYPE_HOMEPAGE for safety.
12854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.TYPE, Website.TYPE_HOMEPAGE);
12864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mBirthday)) {
12914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
12934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
12944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.START_DATE, mBirthday);
12954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
12964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
12974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1299c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        if (!TextUtils.isEmpty(mAnniversary)) {
1300c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1301c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
1302c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
130342f5f84d9d501893bc14702276f0300ca8230bb5Daisuke Miyakawa            builder.withValue(Event.START_DATE, mAnniversary);
1304c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_ANNIVERSARY);
1305c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            operationList.add(builder.build());
1306c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        }
1307c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa
130888d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        if (mSipList != null && !mSipList.isEmpty()) {
130988d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            for (String sipAddress : mSipList) {
131088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
131188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
131288d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(SipAddress.SIP_ADDRESS, sipAddress);
131388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                operationList.add(builder.build());
131488d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
131588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        }
131688d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa
13174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList != null) {
13184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (List<String> customPropertyList : mAndroidCustomPropertyList) {
13194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int size = customPropertyList.size();
13204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (size < 2 || TextUtils.isEmpty(customPropertyList.get(0))) {
13214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    continue;
13224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (size > VCardConstants.MAX_DATA_COLUMN + 1) {
13234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    size = VCardConstants.MAX_DATA_COLUMN + 1;
13244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    customPropertyList =
13254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        customPropertyList.subList(0, VCardConstants.MAX_DATA_COLUMN + 2);
13264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int i = 0;
13294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (final String customPropertyValue : customPropertyList) {
13304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i == 0) {
13314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        final String mimeType = customPropertyValue;
13324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
13344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.withValue(Data.MIMETYPE, mimeType);
13354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {  // 1 <= i && i <= MAX_DATA_COLUMNS
13364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!TextUtils.isEmpty(customPropertyValue)) {
13374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.withValue("data" + i, customPropertyValue);
13384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
13394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
13404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    i++;
13424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (myGroupsId != null) {
13484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
13504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
13514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(GroupMembership.GROUP_SOURCE_ID, myGroupsId);
13524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
13534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        try {
13564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderResult[] results = resolver.applyBatch(
13574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        ContactsContract.AUTHORITY, operationList);
13584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // the first result is always the raw_contact. return it's uri so
13594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // that it can be found later. do null checking for badly behaving
13604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // ContentResolvers
13614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (results == null || results.length == 0 || results[0] == null)
13624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                ? null
13634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                : results[0].uri;
13644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } catch (RemoteException e) {
13654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
13664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return null;
13674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } catch (OperationApplicationException e) {
13684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
13694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return null;
13704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
13724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver) {
13744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return buildFromResolver(resolver, Contacts.CONTENT_URI);
13754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
13764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver, Uri uri) {
13784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return null;
13804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
13814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private boolean nameFieldsAreEmpty() {
13834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return (TextUtils.isEmpty(mFamilyName)
13844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mMiddleName)
13854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mGivenName)
13864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPrefix)
13874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mSuffix)
13884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mFormattedName)
13894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFamilyName)
13904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticMiddleName)
13914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticGivenName)
13924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFullName));
13934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
13944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public boolean isIgnorable() {
13964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return getDisplayName().length() == 0;
13974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
13984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String listToString(List<String> list){
14004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = list.size();
14014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 1) {
14024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
14034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
14044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String type : list) {
14054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(type);
14064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (i < size - 1) {
14074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(";");
14084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
14114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (size == 1) {
14124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return list.get(0);
14134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
14144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "";
14154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // All getter methods should be used carefully, since they may change
14194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // in the future as of 2009-10-05, on which I cannot be sure this structure
14204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // is completely consolidated.
14214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    //
14224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Also note that these getter methods should be used only after
14234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // all properties being pushed into this object. If not, incorrect
14244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // value will "be stored in the local cache and" be returned to you.
14254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFamilyName() {
14274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFamilyName;
14284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getGivenName() {
14314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mGivenName;
14324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getMiddleName() {
14354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mMiddleName;
14364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPrefix() {
14394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPrefix;
14404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getSuffix() {
14434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mSuffix;
14444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFullName() {
14474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFormattedName;
14484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFamilyName() {
14514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFamilyName;
14524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticGivenName() {
14554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticGivenName;
14564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticMiddleName() {
14594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticMiddleName;
14604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFullName() {
14634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFullName;
14644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNickNameList() {
14674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNickNameList;
14684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getBirthday() {
14714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mBirthday;
14724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNotes() {
14754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNoteList;
14764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhoneData> getPhoneList() {
14794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneList;
14804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<EmailData> getEmailList() {
14834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mEmailList;
14844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PostalData> getPostalList() {
14874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPostalList;
14884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<OrganizationData> getOrganizationList() {
14914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mOrganizationList;
14924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<ImData> getImList() {
14954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mImList;
14964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhotoData> getPhotoList() {
14994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhotoList;
15004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getWebsiteList() {
15034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mWebsiteList;
15044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getDisplayName() {
15074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
15084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            constructDisplayName();
15094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
15104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mDisplayName;
15114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}
1513