Java tutorial
/** This file derived from Cordova Android Project available under the Apache 2.0 License Please refer to APACHE-LICENCE2.0.txt for attributions */ /** ============== GPL License ============== This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ============== Commercial License============== https://github.com/karuradev/licenses/blob/master/toc.txt */ package com.karura.framework.plugins.utils; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.accounts.Account; import android.accounts.AccountManager; import android.annotation.SuppressLint; import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentUris; import android.content.ContentValues; import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; import android.provider.ContactsContract; import android.text.TextUtils; import android.util.Log; import com.karura.framework.BuildConfig; /** * An implementation of {@link ContactAccessor} that uses current Contacts API. This class should be used on Eclair or * beyond, but would not work on any earlier release of Android. As a matter of fact, it could not even be loaded. * <p> * This implementation has several advantages: * <ul> * <li>It sees contacts from multiple accounts. * <li>It works with aggregated contacts. So for example, if the contact is the result of aggregation of two raw * contacts from different accounts, it may return the name from one and the phone number from the other. * <li>It is efficient because it uses the more efficient current API. * <li>Not obvious in this particular example, but it has access to new kinds of data available exclusively through the * new APIs. Exercise for the reader: add support for nickname (see * {@link android.provider.ContactsContract.CommonDataKinds.Nickname}) or social status updates (see * {@link android.provider.ContactsContract.StatusUpdates}). * </ul> */ @SuppressLint("DefaultLocale") public class ContactAccessorSdk5 extends ContactAccessor { /** * Keep the photo size under the 1 MB blog limit. */ private static final long MAX_PHOTO_SIZE = 1048576; /* * <anything>@<anything >.<anything> */ private static final String EMAIL_REGEXP = ".+@.+\\.+.+"; static { dbMap.put(CONTACT_ID, ContactsContract.Data.CONTACT_ID); dbMap.put(DISPLAY_NAME, ContactsContract.Contacts.DISPLAY_NAME); dbMap.put(NAME, ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME); dbMap.put(FAMILY_NAME, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME); dbMap.put(GIVEN_NAME, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME); dbMap.put(MIDDLE_NAME, ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME); dbMap.put(PREFIX, ContactsContract.CommonDataKinds.StructuredName.PREFIX); dbMap.put(SUFFIX, ContactsContract.CommonDataKinds.StructuredName.SUFFIX); dbMap.put(PHONE_NUMBER, ContactsContract.CommonDataKinds.Phone.NUMBER); dbMap.put(EMAIL, ContactsContract.CommonDataKinds.Email.DATA); dbMap.put(FORMATTED_ADDRESS, ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); dbMap.put(STREET, ContactsContract.CommonDataKinds.StructuredPostal.STREET); dbMap.put(CITY, ContactsContract.CommonDataKinds.StructuredPostal.CITY); dbMap.put(REGION, ContactsContract.CommonDataKinds.StructuredPostal.REGION); dbMap.put(POSTCODE, ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE); dbMap.put(COUNTRY, ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY); dbMap.put(IMS, ContactsContract.CommonDataKinds.Im.DATA); dbMap.put(ORGANIZATION, ContactsContract.CommonDataKinds.Organization.COMPANY); dbMap.put(DEPARTMENT, ContactsContract.CommonDataKinds.Organization.DEPARTMENT); dbMap.put(TITLE, ContactsContract.CommonDataKinds.Organization.TITLE); dbMap.put(BIRTHDAY, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE); dbMap.put(NOTE, ContactsContract.CommonDataKinds.Note.NOTE); dbMap.put(PHOTO, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); dbMap.put(URLS, ContactsContract.CommonDataKinds.Website.URL); } @Override public int getCount(JSONArray fields, String selection) { // TODO Auto-generated method stub return 0; } /** * This method takes the fields required and search options in order to produce an array of contacts that matches * the criteria provided. * * @param fields * an array of items to be used as search criteria * @param options * that can be applied to contact searching * @return an array of contacts */ @Override public JSONArray search(JSONArray fields, String where, int startIndex, int limit) { // Get the find options String searchTerm = null; if (TextUtils.isEmpty(where)) { searchTerm = "%"; } else { searchTerm = "%" + where + "%"; } if (BuildConfig.DEBUG) { Log.d(LOG_TAG, "Search Term = " + searchTerm); Log.d(LOG_TAG, "Field Length = " + fields.length()); Log.d(LOG_TAG, "Fields = " + fields.toString()); } // Loop through the fields the user provided to see what data should be // returned. HashMap<String, Boolean> populate = buildPopulationSet(fields); // Build the ugly where clause and where arguments for one big query. WhereOptions whereOptions = buildWhereClause(fields, searchTerm, startIndex, limit); // Get all the id's where the search term matches the fields passed in. Cursor idCursor = getContext().getContentResolver().query(ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.CONTACT_ID }, whereOptions.getWhere(), whereOptions.getWhereArgs(), ContactsContract.Data.CONTACT_ID + " ASC " + whereOptions.getLimit()); // Create a set of unique ids Set<String> contactIds = new HashSet<String>(); int idColumn = -1; while (idCursor.moveToNext()) { if (idColumn < 0) { idColumn = idCursor.getColumnIndex(ContactsContract.Data.CONTACT_ID); } contactIds.add(idCursor.getString(idColumn)); } idCursor.close(); // Build a query that only looks at ids WhereOptions idOptions = buildIdClause(contactIds, searchTerm); // Determine which columns we should be fetching. HashSet<String> columnsToFetch = new HashSet<String>(); columnsToFetch.add(ContactsContract.Data.CONTACT_ID); columnsToFetch.add(ContactsContract.Data.RAW_CONTACT_ID); columnsToFetch.add(ContactsContract.Data.MIMETYPE); if (isRequired(DISPLAY_NAME, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME); } if (isRequired(NAME, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.PREFIX); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredName.SUFFIX); } if (isRequired(PHONE_NUMBER, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Phone._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Phone.NUMBER); columnsToFetch.add(ContactsContract.CommonDataKinds.Phone.TYPE); } if (isRequired(EMAIL, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Email._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Email.DATA); columnsToFetch.add(ContactsContract.CommonDataKinds.Email.TYPE); } if (isRequired(FORMATTED_ADDRESS, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Organization.TYPE); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.STREET); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.CITY); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.REGION); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE); columnsToFetch.add(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY); } if (isRequired(ORGANIZATION, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Organization._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Organization.TYPE); columnsToFetch.add(ContactsContract.CommonDataKinds.Organization.DEPARTMENT); columnsToFetch.add(ContactsContract.CommonDataKinds.Organization.COMPANY); columnsToFetch.add(ContactsContract.CommonDataKinds.Organization.TITLE); } if (isRequired(IMS, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Im._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Im.DATA); columnsToFetch.add(ContactsContract.CommonDataKinds.Im.TYPE); } if (isRequired(NOTE, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Note.NOTE); } if (isRequired(URLS, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Website._ID); columnsToFetch.add(ContactsContract.CommonDataKinds.Website.URL); columnsToFetch.add(ContactsContract.CommonDataKinds.Website.TYPE); } if (isRequired(BIRTHDAY, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Event.START_DATE); columnsToFetch.add(ContactsContract.CommonDataKinds.Event.TYPE); } if (isRequired(PHOTO, populate)) { columnsToFetch.add(ContactsContract.CommonDataKinds.Photo._ID); } // Do the id query Cursor c = getContext().getContentResolver().query(ContactsContract.Data.CONTENT_URI, columnsToFetch.toArray(new String[] {}), idOptions.getWhere(), idOptions.getWhereArgs(), ContactsContract.Data.CONTACT_ID + " ASC"); JSONArray contacts = populateContactArray(populate, c); return contacts; } /** * Take the search criteria passed into the method and create a SQL WHERE clause. * * @param fields * the properties to search against * @param searchTerm * the string to search for * @param limit * @param startIndex * @return an object containing the selection and selection args */ private WhereOptions buildWhereClause(JSONArray fields, String searchTerm, int startIndex, int limit) { ArrayList<String> where = new ArrayList<String>(); ArrayList<String> whereArgs = new ArrayList<String>(); WhereOptions options = new WhereOptions(); options.setLimit(startIndex, limit); if ("%".equals(searchTerm)) { options.setWhere("(" + ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? )"); options.setWhereArgs(new String[] { searchTerm }); return options; } /* * Special case where the user wants all fields returned */ boolean allFields = isGetAllFieldsSearch(fields); String key; try { for (int i = 0; i < fields.length(); i++) { key = fields.getString(i); if (allFields || key.equals(CONTACT_ID)) { where.add("(" + dbMap.get(key) + " = ? )"); whereArgs.add(searchTerm.substring(1, searchTerm.length() - 1)); } if (allFields || key.startsWith(DISPLAY_NAME)) { where.add("(" + dbMap.get(key) + " LIKE ? )"); whereArgs.add(searchTerm); } if (allFields || key.startsWith(NAME)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); } if (allFields || key.startsWith(PHONE_NUMBER)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); } if (allFields || key.startsWith(EMAIL)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); } if (allFields || key.startsWith(FORMATTED_ADDRESS)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE); } if (allFields || key.equals(IMS)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE); } if (allFields || key.startsWith(ORGANIZATION)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); } if (allFields || key.equals(NOTE)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE); } if (allFields || key.equals(URLS)) { where.add("(" + dbMap.get(key) + " LIKE ? AND " + ContactsContract.Data.MIMETYPE + " = ? )"); whereArgs.add(searchTerm); whereArgs.add(ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); } if (allFields) { break; } } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } // Creating the where string StringBuffer selection = new StringBuffer(); for (int i = 0; i < where.size(); i++) { selection.append(where.get(i)); if (i != (where.size() - 1)) { selection.append(" OR "); } } options.setWhere(selection.toString()); // Creating the where args array String[] selectionArgs = new String[whereArgs.size()]; for (int i = 0; i < whereArgs.size(); i++) { selectionArgs[i] = whereArgs.get(i); } options.setWhereArgs(selectionArgs); return options; } /** * A special search that finds one contact by id * * @param id * contact to find by id * @return a JSONObject representing the contact * @throws JSONException */ public JSONObject getContactById(String id) throws JSONException { // Do the id query Cursor c = getContext().getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.CONTACT_ID + " = ? ", new String[] { id }, ContactsContract.Data.CONTACT_ID + " ASC"); JSONArray fields = new JSONArray(); fields.put("*"); HashMap<String, Boolean> populate = buildPopulationSet(fields); JSONArray contacts = populateContactArray(populate, c); if (contacts.length() == 1) { return contacts.getJSONObject(0); } else { return null; } } /** * Creates an array of contacts from the cursor you pass in * * @param populate * whether or not you should populate a certain value * @param c * the cursor * @return a JSONArray of contacts */ private JSONArray populateContactArray(HashMap<String, Boolean> populate, Cursor c) { String contactId = ""; String rawId = ""; String oldContactId = ""; boolean newContact = true; String mimetype = ""; JSONArray contacts = new JSONArray(); JSONObject contact = new JSONObject(); JSONArray organizations = new JSONArray(); JSONArray addresses = new JSONArray(); JSONArray phones = new JSONArray(); JSONArray emails = new JSONArray(); JSONArray ims = new JSONArray(); JSONArray websites = new JSONArray(); JSONArray photos = new JSONArray(); // Column indices int colContactId = c.getColumnIndex(ContactsContract.Data.CONTACT_ID); int colRawContactId = c.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID); int colMimetype = c.getColumnIndex(ContactsContract.Data.MIMETYPE); int colDisplayName = c.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME); int colNote = c.getColumnIndex(ContactsContract.CommonDataKinds.Note.NOTE); int colBirthday = c.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE); int colEventType = c.getColumnIndex(ContactsContract.CommonDataKinds.Event.TYPE); int index = 0; if (c.getCount() > 0) { while (c.moveToNext()) { try { contactId = c.getString(colContactId); rawId = c.getString(colRawContactId); // If we are in the first row set the oldContactId if (c.getPosition() == 0) { oldContactId = contactId; } // When the contact ID changes we need to push the Contact // object // to the array of contacts and create new objects. if (!oldContactId.equals(contactId)) { // Populate the Contact object with it's arrays // and push the contact into the contacts array contacts.put(populateContact(contact, organizations, addresses, phones, emails, ims, websites, photos)); // Clean up the objects contact = new JSONObject(); organizations = new JSONArray(); addresses = new JSONArray(); phones = new JSONArray(); emails = new JSONArray(); ims = new JSONArray(); websites = new JSONArray(); photos = new JSONArray(); // Set newContact to true as we are starting to populate // a new contact newContact = true; } // When we detect a new contact set the ID and display name. // These fields are available in every row in the result set // returned. if (newContact) { newContact = false; contact.put("id", contactId); contact.put("rawId", rawId); contact.put("index", index++); } // Grab the mimetype of the current row as it will be used // in a lot of comparisons mimetype = c.getString(colMimetype); if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) { contact.put(DISPLAY_NAME, c.getString(colDisplayName)); } if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) && isRequired(NAME, populate)) { contact.put(NAME, nameQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) && isRequired(PHONE_NUMBER, populate)) { phones.put(phoneQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) && isRequired(EMAIL, populate)) { emails.put(emailQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) && isRequired(FORMATTED_ADDRESS, populate)) { addresses.put(addressQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE) && isRequired(ORGANIZATION, populate)) { organizations.put(organizationQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) && isRequired(IMS, populate)) { ims.put(imQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE) && isRequired(NOTE, populate)) { contact.put(NOTE, c.getString(colNote)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE) && isRequired(URLS, populate)) { websites.put(websiteQuery(c)); } else if (mimetype.equals(ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE)) { if (isRequired(BIRTHDAY, populate) && ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY == c.getInt(colEventType)) { contact.put(BIRTHDAY, c.getString(colBirthday)); } } else if (mimetype.equals(ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE) && isRequired(PHOTO, populate)) { photos.put(photoQuery(c, contactId)); } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } // Set the old contact ID oldContactId = contactId; } contacts.put(populateContact(contact, organizations, addresses, phones, emails, ims, websites, photos)); } c.close(); return contacts; } /** * Builds a where clause all all the ids passed into the method * * @param contactIds * a set of unique contact ids * @param searchTerm * what to search for * @return an object containing the selection and selection args */ private WhereOptions buildIdClause(Set<String> contactIds, String searchTerm) { WhereOptions options = new WhereOptions(); // This clause means that there are specific ID's to be populated Iterator<String> it = contactIds.iterator(); StringBuffer buffer = new StringBuffer("("); while (it.hasNext()) { buffer.append("'" + it.next() + "'"); if (it.hasNext()) { buffer.append(","); } } buffer.append(")"); options.setWhere(ContactsContract.Data.CONTACT_ID + " IN " + buffer.toString()); options.setWhereArgs(null); return options; } /** * Create a new contact using a JSONObject to hold all the data. * * @param contact * @param organizations * array of organizations * @param addresses * array of addresses * @param phones * array of phones * @param emails * array of emails * @param ims * array of instant messenger addresses * @param websites * array of websites * @param photos * @return */ private JSONObject populateContact(JSONObject contact, JSONArray organizations, JSONArray addresses, JSONArray phones, JSONArray emails, JSONArray ims, JSONArray websites, JSONArray photos) { try { // Only return the array if it has at least one entry if (organizations.length() > 0) { contact.put("organizations", organizations); } if (addresses.length() > 0) { contact.put("addresses", addresses); } if (phones.length() > 0) { contact.put("phoneNumbers", phones); } if (emails.length() > 0) { contact.put("emails", emails); } if (ims.length() > 0) { contact.put("ims", ims); } if (websites.length() > 0) { contact.put("urls", websites); } if (photos.length() > 0) { contact.put("photos", photos); } } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return contact; } /** * Create a ContactOrganization JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactOrganization */ private JSONObject organizationQuery(Cursor cursor) { JSONObject organization = new JSONObject(); try { organization.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization._ID))); organization.put("pref", false); // Android does not store pref // attribute organization.put("type", getOrgType( cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE)))); organization.put("department", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DEPARTMENT))); organization.put("name", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.COMPANY))); organization.put("title", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return organization; } /** * Create a ContactAddress JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactAddress */ private JSONObject addressQuery(Cursor cursor) { JSONObject address = new JSONObject(); try { address.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal._ID))); address.put("pref", false); // Android does not store pref attribute address.put("type", getAddressType( cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TYPE)))); address.put("formatted", cursor.getString( cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS))); address.put("streetAddress", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET))); address.put("locality", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY))); address.put("region", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION))); address.put("postalCode", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE))); address.put("country", cursor .getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return address; } /** * Create a ContactName JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactName */ private JSONObject nameQuery(Cursor cursor) { JSONObject contactName = new JSONObject(); try { int colIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME); String familyName = cursor.getString(colIndex); colIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME); String givenName = cursor.getString(colIndex); colIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME); String middleName = cursor.getString(colIndex); colIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.PREFIX); String honorificPrefix = cursor.getString(colIndex); colIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.SUFFIX); String honorificSuffix = cursor.getString(colIndex); // Create the formatted name StringBuffer formatted = new StringBuffer(""); if (honorificPrefix != null) { formatted.append(honorificPrefix + " "); } if (givenName != null) { formatted.append(givenName + " "); } if (middleName != null) { formatted.append(middleName + " "); } if (familyName != null) { formatted.append(familyName); } if (honorificSuffix != null) { formatted.append(" " + honorificSuffix); } contactName.put("familyName", familyName); contactName.put("givenName", givenName); contactName.put("middleName", middleName); contactName.put("honorificPrefix", honorificPrefix); contactName.put("honorificSuffix", honorificSuffix); contactName.put("formatted", formatted); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return contactName; } /** * Create a ContactField JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactField */ private JSONObject phoneQuery(Cursor cursor) { JSONObject phoneNumber = new JSONObject(); try { phoneNumber.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); phoneNumber.put("pref", false); // Android does not store pref // attribute phoneNumber.put("value", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); phoneNumber.put("type", getPhoneType( cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } catch (Exception excp) { Log.e(LOG_TAG, excp.getMessage(), excp); } return phoneNumber; } /** * Create a ContactField JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactField */ private JSONObject emailQuery(Cursor cursor) { JSONObject email = new JSONObject(); try { email.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email._ID))); email.put("pref", false); // Android does not store pref attribute email.put("value", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA))); email.put("type", getContactType( cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return email; } /** * Create a ContactField JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactField */ private JSONObject imQuery(Cursor cursor) { JSONObject im = new JSONObject(); try { im.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im._ID))); im.put("pref", false); // Android does not store pref attribute im.put("value", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA))); im.put("type", getImType( cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Im.PROTOCOL)))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return im; } /** * Create a ContactField JSONObject * * @param cursor * the current database row * @return a JSONObject representing a ContactField */ private JSONObject websiteQuery(Cursor cursor) { JSONObject website = new JSONObject(); try { website.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website._ID))); website.put("pref", false); // Android does not store pref attribute website.put("value", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.URL))); website.put("type", getContactType( cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Website.TYPE)))); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return website; } /** * Create a ContactField JSONObject * * @param contactId * @return a JSONObject representing a ContactField */ private JSONObject photoQuery(Cursor cursor, String contactId) { JSONObject photo = new JSONObject(); try { photo.put("id", cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo._ID))); photo.put("pref", false); photo.put("type", "url"); Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, (new Long(contactId))); Uri photoUri = Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY); photo.put("value", photoUri.toString()); } catch (JSONException e) { Log.e(LOG_TAG, e.getMessage(), e); } return photo; } @Override /** * This method will save a contact object into the devices contacts database. * * @param contact the contact to be saved. * @returns the id if the contact is successfully saved, null otherwise. */ public String save(JSONObject contact) { AccountManager mgr = AccountManager.get(getContext()); Account[] accounts = mgr.getAccounts(); String accountName = null; String accountType = null; if (accounts.length == 1) { accountName = accounts[0].name; accountType = accounts[0].type; } else if (accounts.length > 1) { for (Account a : accounts) { if (a.type.contains("eas") && a.name.matches(EMAIL_REGEXP)) /* * Exchange ActiveSync */ { accountName = a.name; accountType = a.type; break; } } if (accountName == null) { for (Account a : accounts) { if (a.type.contains("com.google") && a.name.matches(EMAIL_REGEXP)) /* * Google sync provider */ { accountName = a.name; accountType = a.type; break; } } } if (accountName == null) { for (Account a : accounts) { if (a.name.matches(EMAIL_REGEXP)) /* * Last resort, just look for an email address... */ { accountName = a.name; accountType = a.type; break; } } } } String id = getJsonString(contact, "id"); // Create new contact if (id == null) { return createNewContact(contact, accountType, accountName); } // Modify existing contact else { return modifyContact(id, contact, accountType, accountName); } } /** * Creates a new contact and stores it in the database * * @param id * the raw contact id which is required for linking items to the contact * @param contact * the contact to be saved * @param account * the account to be saved under */ private String modifyContact(String id, JSONObject contact, String accountType, String accountName) { // Get the RAW_CONTACT_ID which is needed to insert new values in an // already existing contact. // But not needed to update existing values. int rawId = Integer.valueOf(getJsonString(contact, "rawId")); // Create a list of attributes to add to the contact database ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); // Add contact type ops.add(ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName).build()); // Modify name JSONObject name; try { String displayName = getJsonString(contact, "displayName"); name = contact.getJSONObject("name"); if (displayName != null || name != null) { ContentProviderOperation.Builder builder = ContentProviderOperation .newUpdate(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { id, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE }); if (displayName != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName); } String familyName = getJsonString(name, "familyName"); if (familyName != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, familyName); } String middleName = getJsonString(name, "middleName"); if (middleName != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, middleName); } String givenName = getJsonString(name, "givenName"); if (givenName != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, givenName); } String honorificPrefix = getJsonString(name, "honorificPrefix"); if (honorificPrefix != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, honorificPrefix); } String honorificSuffix = getJsonString(name, "honorificSuffix"); if (honorificSuffix != null) { builder.withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, honorificSuffix); } ops.add(builder.build()); } } catch (JSONException e1) { Log.d(LOG_TAG, "Could not get name"); } // Modify phone numbers JSONArray phones = null; try { phones = contact.getJSONArray("phoneNumbers"); if (phones != null) { // Delete all the phones if (phones.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a phone else { for (int i = 0; i < phones.length(); i++) { JSONObject phone = (JSONObject) phones.get(i); String phoneId = getJsonString(phone, "id"); // This is a new phone so do a DB insert if (phoneId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, getJsonString(phone, "value")); contentValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, getPhoneType(getJsonString(phone, "type"))); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing phone so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Phone._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { phoneId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, getJsonString(phone, "value")) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, getPhoneType(getJsonString(phone, "type"))) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get phone numbers"); } // Modify emails JSONArray emails = null; try { emails = contact.getJSONArray("emails"); if (emails != null) { // Delete all the emails if (emails.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a email else { for (int i = 0; i < emails.length(); i++) { JSONObject email = (JSONObject) emails.get(i); String emailId = getJsonString(email, "id"); // This is a new email so do a DB insert if (emailId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.Email.DATA, getJsonString(email, "value")); contentValues.put(ContactsContract.CommonDataKinds.Email.TYPE, getContactType(getJsonString(email, "type"))); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing email so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Email._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { emailId, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Email.DATA, getJsonString(email, "value")) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, getContactType(getJsonString(email, "type"))) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get emails"); } // Modify addresses JSONArray addresses = null; try { addresses = contact.getJSONArray("addresses"); if (addresses != null) { // Delete all the addresses if (addresses.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a address else { for (int i = 0; i < addresses.length(); i++) { JSONObject address = (JSONObject) addresses.get(i); String addressId = getJsonString(address, "id"); // This is a new address so do a DB insert if (addressId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type"))); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted")); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress")); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality")); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.REGION, getJsonString(address, "region")); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, getJsonString(address, "postalCode")); contentValues.put(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, getJsonString(address, "country")); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing address so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.StructuredPostal._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { addressId, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type"))) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, getJsonString(address, "region")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, getJsonString(address, "postalCode")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, getJsonString(address, "country")) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get addresses"); } // Modify organizations JSONArray organizations = null; try { organizations = contact.getJSONArray("organizations"); if (organizations != null) { // Delete all the organizations if (organizations.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a organization else { for (int i = 0; i < organizations.length(); i++) { JSONObject org = (JSONObject) organizations.get(i); String orgId = getJsonString(org, "id"); // This is a new organization so do a DB insert if (orgId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type"))); contentValues.put(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department")); contentValues.put(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name")); contentValues.put(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title")); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing organization so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Organization._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { orgId, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type"))) .withValue(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department")) .withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name")) .withValue(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title")) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get organizations"); } // Modify IMs JSONArray ims = null; try { ims = contact.getJSONArray("ims"); if (ims != null) { // Delete all the ims if (ims.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a im else { for (int i = 0; i < ims.length(); i++) { JSONObject im = (JSONObject) ims.get(i); String imId = getJsonString(im, "id"); // This is a new IM so do a DB insert if (imId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.Im.DATA, getJsonString(im, "value")); contentValues.put(ContactsContract.CommonDataKinds.Im.TYPE, getImType(getJsonString(im, "type"))); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing IM so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Im._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { imId, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Im.DATA, getJsonString(im, "value")) .withValue(ContactsContract.CommonDataKinds.Im.TYPE, getContactType(getJsonString(im, "type"))) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get emails"); } // Modify note String note = getJsonString(contact, "note"); ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection(ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { id, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note).build()); // Modify nickname String nickname = getJsonString(contact, "nickname"); if (nickname != null) { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { id, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Nickname.NAME, nickname).build()); } // Modify urls JSONArray websites = null; try { websites = contact.getJSONArray("urls"); if (websites != null) { // Delete all the websites if (websites.length() == 0) { Log.d(LOG_TAG, "This means we should be deleting all the phone numbers."); ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a website else { for (int i = 0; i < websites.length(); i++) { JSONObject website = (JSONObject) websites.get(i); String websiteId = getJsonString(website, "id"); // This is a new website so do a DB insert if (websiteId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.CommonDataKinds.Website.DATA, getJsonString(website, "value")); contentValues.put(ContactsContract.CommonDataKinds.Website.TYPE, getContactType(getJsonString(website, "type"))); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing website so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Website._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { websiteId, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.CommonDataKinds.Website.DATA, getJsonString(website, "value")) .withValue(ContactsContract.CommonDataKinds.Website.TYPE, getContactType(getJsonString(website, "type"))) .build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get websites"); } // Modify birthday String birthday = getJsonString(contact, "birthday"); if (birthday != null) { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=? AND " + ContactsContract.CommonDataKinds.Event.TYPE + "=?", new String[] { id, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE, new String("" + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) }) .withValue(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) .withValue(ContactsContract.CommonDataKinds.Event.START_DATE, birthday).build()); } // Modify photos JSONArray photos = null; try { photos = contact.getJSONArray("photos"); if (photos != null) { // Delete all the photos if (photos.length() == 0) { ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { "" + rawId, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE }) .build()); } // Modify or add a photo else { for (int i = 0; i < photos.length(); i++) { JSONObject photo = (JSONObject) photos.get(i); String photoId = getJsonString(photo, "id"); byte[] bytes = getPhotoBytes(getJsonString(photo, "value")); // This is a new photo so do a DB insert if (photoId == null) { ContentValues contentValues = new ContentValues(); contentValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawId); contentValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE); contentValues.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1); contentValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValues(contentValues).build()); } // This is an existing photo so do a DB update else { ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.CommonDataKinds.Photo._ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?", new String[] { photoId, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE }) .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1) .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes).build()); } } } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get photos"); } boolean retVal = true; // Modify contact try { getContext().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); } catch (RemoteException e) { Log.e(LOG_TAG, e.getMessage(), e); Log.e(LOG_TAG, Log.getStackTraceString(e), e); retVal = false; } catch (OperationApplicationException e) { Log.e(LOG_TAG, e.getMessage(), e); Log.e(LOG_TAG, Log.getStackTraceString(e), e); retVal = false; } // if the save was a success return the contact ID if (retVal) { return id; } else { return null; } } /** * Add a website to a list of database actions to be performed * * @param ops * the list of database actions * @param website * the item to be inserted */ private void insertWebsite(ArrayList<ContentProviderOperation> ops, JSONObject website) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Website.DATA, getJsonString(website, "value")) .withValue(ContactsContract.CommonDataKinds.Website.TYPE, getContactType(getJsonString(website, "type"))) .build()); } /** * Add an im to a list of database actions to be performed * * @param ops * the list of database actions * @param im * the item to be inserted */ private void insertIm(ArrayList<ContentProviderOperation> ops, JSONObject im) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Im.DATA, getJsonString(im, "value")) .withValue(ContactsContract.CommonDataKinds.Im.TYPE, getImType(getJsonString(im, "type"))).build()); } /** * Add an organization to a list of database actions to be performed * * @param ops * the list of database actions * @param org * the item to be inserted */ private void insertOrganization(ArrayList<ContentProviderOperation> ops, JSONObject org) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Organization.TYPE, getOrgType(getJsonString(org, "type"))) .withValue(ContactsContract.CommonDataKinds.Organization.DEPARTMENT, getJsonString(org, "department")) .withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, getJsonString(org, "name")) .withValue(ContactsContract.CommonDataKinds.Organization.TITLE, getJsonString(org, "title")) .build()); } /** * Add an address to a list of database actions to be performed * * @param ops * the list of database actions * @param address * the item to be inserted */ private void insertAddress(ArrayList<ContentProviderOperation> ops, JSONObject address) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, getAddressType(getJsonString(address, "type"))) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS, getJsonString(address, "formatted")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, getJsonString(address, "streetAddress")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, getJsonString(address, "locality")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, getJsonString(address, "region")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, getJsonString(address, "postalCode")) .withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, getJsonString(address, "country")) .build()); } /** * Add an email to a list of database actions to be performed * * @param ops * the list of database actions * @param email * the item to be inserted */ private void insertEmail(ArrayList<ContentProviderOperation> ops, JSONObject email) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Email.DATA, getJsonString(email, "value")) .withValue(ContactsContract.CommonDataKinds.Email.TYPE, getContactType(getJsonString(email, "type"))) .build()); } /** * Add a phone to a list of database actions to be performed * * @param ops * the list of database actions * @param phone * the item to be inserted */ private void insertPhone(ArrayList<ContentProviderOperation> ops, JSONObject phone) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, getJsonString(phone, "value")) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, getPhoneType(getJsonString(phone, "type"))) .build()); } /** * Add a phone to a list of database actions to be performed * * @param ops * the list of database actions * @param phone * the item to be inserted */ private void insertPhoto(ArrayList<ContentProviderOperation> ops, JSONObject photo) { byte[] bytes = getPhotoBytes(getJsonString(photo, "value")); ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes).build()); } /** * Gets the raw bytes from the supplied filename * * @param filename * the file to read the bytes from * @return a byte array * @throws IOException */ private byte[] getPhotoBytes(String filename) { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try { int bytesRead = 0; long totalBytesRead = 0; byte[] data = new byte[8192]; InputStream in = getPathFromUri(filename); while ((bytesRead = in.read(data, 0, data.length)) != -1 && totalBytesRead <= MAX_PHOTO_SIZE) { buffer.write(data, 0, bytesRead); totalBytesRead += bytesRead; } in.close(); buffer.flush(); } catch (FileNotFoundException e) { Log.e(LOG_TAG, e.getMessage(), e); } catch (IOException e) { Log.e(LOG_TAG, e.getMessage(), e); } return buffer.toByteArray(); } /** * Get an input stream based on file path or uri content://, http://, file:// * * @param path * @return an input stream * @throws IOException */ private InputStream getPathFromUri(String path) throws IOException { if (path.startsWith("content:")) { Uri uri = Uri.parse(path); return getContext().getContentResolver().openInputStream(uri); } if (path.startsWith("http:") || path.startsWith("https:") || path.startsWith("file:")) { URL url = new URL(path); return url.openStream(); } else { return new FileInputStream(path); } } /** * Creates a new contact and stores it in the database * * @param contact * the contact to be saved * @param account * the account to be saved under */ private String createNewContact(JSONObject contact, String accountType, String accountName) { // Create a list of attributes to add to the contact database ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); // Add contact type ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName).build()); // Add name try { JSONObject name = contact.optJSONObject("name"); String displayName = contact.getString("displayName"); if (displayName != null || name != null) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName) .withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, getJsonString(name, "familyName")) .withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, getJsonString(name, "middleName")) .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, getJsonString(name, "givenName")) .withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, getJsonString(name, "honorificPrefix")) .withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, getJsonString(name, "honorificSuffix")) .build()); } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get name object"); } // Add phone numbers JSONArray phones = null; try { phones = contact.getJSONArray("phoneNumbers"); if (phones != null) { for (int i = 0; i < phones.length(); i++) { JSONObject phone = (JSONObject) phones.get(i); insertPhone(ops, phone); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get phone numbers"); } // Add emails JSONArray emails = null; try { emails = contact.getJSONArray("emails"); if (emails != null) { for (int i = 0; i < emails.length(); i++) { JSONObject email = (JSONObject) emails.get(i); insertEmail(ops, email); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get emails"); } // Add addresses JSONArray addresses = null; try { addresses = contact.getJSONArray("addresses"); if (addresses != null) { for (int i = 0; i < addresses.length(); i++) { JSONObject address = (JSONObject) addresses.get(i); insertAddress(ops, address); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get addresses"); } // Add organizations JSONArray organizations = null; try { organizations = contact.getJSONArray("organizations"); if (organizations != null) { for (int i = 0; i < organizations.length(); i++) { JSONObject org = (JSONObject) organizations.get(i); insertOrganization(ops, org); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get organizations"); } // Add IMs JSONArray ims = null; try { ims = contact.getJSONArray("ims"); if (ims != null) { for (int i = 0; i < ims.length(); i++) { JSONObject im = (JSONObject) ims.get(i); insertIm(ops, im); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get emails"); } // Add note String note = getJsonString(contact, "note"); if (note != null) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Note.NOTE, note).build()); } // Add nickname String nickname = getJsonString(contact, "nickname"); if (nickname != null) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Nickname.NAME, nickname).build()); } // Add urls JSONArray websites = null; try { websites = contact.getJSONArray("urls"); if (websites != null) { for (int i = 0; i < websites.length(); i++) { JSONObject website = (JSONObject) websites.get(i); insertWebsite(ops, website); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get websites"); } // Add birthday String birthday = getJsonString(contact, "birthday"); if (birthday != null) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY) .withValue(ContactsContract.CommonDataKinds.Event.START_DATE, birthday).build()); } // Add photos JSONArray photos = null; try { photos = contact.getJSONArray("photos"); if (photos != null) { for (int i = 0; i < photos.length(); i++) { JSONObject photo = (JSONObject) photos.get(i); insertPhoto(ops, photo); } } } catch (JSONException e) { Log.d(LOG_TAG, "Could not get photos"); } String newId = null; // Add contact try { ContentProviderResult[] cpResults = getContext().getContentResolver() .applyBatch(ContactsContract.AUTHORITY, ops); if (cpResults.length >= 0) { newId = cpResults[0].uri.getLastPathSegment(); } } catch (RemoteException e) { Log.e(LOG_TAG, e.getMessage(), e); } catch (OperationApplicationException e) { Log.e(LOG_TAG, e.getMessage(), e); } return newId; } @Override /** * This method will remove a Contact from the database based on ID. * @param id the unique ID of the contact to remove */ public boolean remove(String id) { int result = 0; Cursor cursor = getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + " = ?", new String[] { id }, null); if (cursor.getCount() == 1) { cursor.moveToFirst(); String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey); result = getContext().getContentResolver().delete(uri, null, null); } else { Log.d(LOG_TAG, "Could not find contact with ID"); } return (result > 0) ? true : false; } /************************************************************************** * * All methods below this comment are used to convert from JavaScript text types to Android integer types and vice * versa. * *************************************************************************/ /** * Converts a string from the W3C Contact API to it's Android int value. * * @param string * @return Android int value */ private int getPhoneType(String string) { int type = ContactsContract.CommonDataKinds.Phone.TYPE_OTHER; if (string != null) { if ("home".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_HOME; } else if ("mobile".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE; } else if ("work".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_WORK; } else if ("work fax".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK; } else if ("home fax".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME; } else if ("fax".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK; } else if ("pager".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_PAGER; } else if ("other".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_OTHER; } else if ("car".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_CAR; } else if ("company main".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN; } else if ("isdn".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_ISDN; } else if ("main".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_MAIN; } else if ("other fax".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX; } else if ("radio".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_RADIO; } else if ("telex".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_TELEX; } else if ("work mobile".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE; } else if ("work pager".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER; } else if ("assistant".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_ASSISTANT; } else if ("mms".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_MMS; } else if ("callback".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_CALLBACK; } else if ("tty ttd".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD; } else if ("custom".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM; } } return type; } /** * getPhoneType converts an Android phone type into a string * * @param type * @return phone type as string. */ private String getPhoneType(int type) { String stringType; switch (type) { case ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM: stringType = "custom"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_HOME: stringType = "home fax"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK: stringType = "work fax"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_HOME: stringType = "home"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: stringType = "mobile"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_PAGER: stringType = "pager"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: stringType = "work"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_CALLBACK: stringType = "callback"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_CAR: stringType = "car"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_COMPANY_MAIN: stringType = "company main"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_OTHER_FAX: stringType = "other fax"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_RADIO: stringType = "radio"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_TELEX: stringType = "telex"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_TTY_TDD: stringType = "tty tdd"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE: stringType = "work mobile"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_PAGER: stringType = "work pager"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_ASSISTANT: stringType = "assistant"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_MMS: stringType = "mms"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_ISDN: stringType = "isdn"; break; case ContactsContract.CommonDataKinds.Phone.TYPE_OTHER: default: stringType = "other"; break; } return stringType; } /** * Converts a string from the W3C Contact API to it's Android int value. * * @param string * @return Android int value */ private int getContactType(String string) { int type = ContactsContract.CommonDataKinds.Email.TYPE_OTHER; if (string != null) { if ("home".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Email.TYPE_HOME; } else if ("work".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Email.TYPE_WORK; } else if ("other".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Email.TYPE_OTHER; } else if ("mobile".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Email.TYPE_MOBILE; } else if ("custom".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM; } } return type; } /** * getPhoneType converts an Android phone type into a string * * @param type * @return phone type as string. */ private String getContactType(int type) { String stringType; switch (type) { case ContactsContract.CommonDataKinds.Email.TYPE_CUSTOM: stringType = "custom"; break; case ContactsContract.CommonDataKinds.Email.TYPE_HOME: stringType = "home"; break; case ContactsContract.CommonDataKinds.Email.TYPE_WORK: stringType = "work"; break; case ContactsContract.CommonDataKinds.Email.TYPE_MOBILE: stringType = "mobile"; break; case ContactsContract.CommonDataKinds.Email.TYPE_OTHER: default: stringType = "other"; break; } return stringType; } /** * Converts a string from the W3C Contact API to it's Android int value. * * @param string * @return Android int value */ private int getOrgType(String string) { int type = ContactsContract.CommonDataKinds.Organization.TYPE_OTHER; if (string != null) { if ("work".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Organization.TYPE_WORK; } else if ("other".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Organization.TYPE_OTHER; } else if ("custom".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Organization.TYPE_CUSTOM; } } return type; } /** * getPhoneType converts an Android phone type into a string * * @param type * @return phone type as string. */ private String getOrgType(int type) { String stringType; switch (type) { case ContactsContract.CommonDataKinds.Organization.TYPE_CUSTOM: stringType = "custom"; break; case ContactsContract.CommonDataKinds.Organization.TYPE_WORK: stringType = "work"; break; case ContactsContract.CommonDataKinds.Organization.TYPE_OTHER: default: stringType = "other"; break; } return stringType; } /** * Converts a string from the W3C Contact API to it's Android int value. * * @param string * @return Android int value */ private int getAddressType(String string) { int type = ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER; if (string != null) { if ("work".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK; } else if ("other".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER; } else if ("home".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME; } } return type; } /** * getPhoneType converts an Android phone type into a string * * @param type * @return phone type as string. */ private String getAddressType(int type) { String stringType; switch (type) { case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME: stringType = "home"; break; case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK: stringType = "work"; break; case ContactsContract.CommonDataKinds.StructuredPostal.TYPE_OTHER: default: stringType = "other"; break; } return stringType; } /** * Converts a string from the W3C Contact API to it's Android int value. * * @param string * @return Android int value */ private int getImType(String string) { int type = ContactsContract.CommonDataKinds.Im.PROTOCOL_CUSTOM; if (string != null) { if ("aim".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_AIM; } else if ("google talk".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK; } else if ("icq".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_ICQ; } else if ("jabber".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER; } else if ("msn".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_MSN; } else if ("netmeeting".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_NETMEETING; } else if ("qq".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ; } else if ("skype".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_SKYPE; } else if ("yahoo".equals(string.toLowerCase(Locale.ENGLISH))) { return ContactsContract.CommonDataKinds.Im.PROTOCOL_YAHOO; } } return type; } }