diff options
Diffstat (limited to 'java/com/android/contacts/common/util/NameConverter.java')
-rw-r--r-- | java/com/android/contacts/common/util/NameConverter.java | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/java/com/android/contacts/common/util/NameConverter.java b/java/com/android/contacts/common/util/NameConverter.java new file mode 100644 index 000000000..ae3275d14 --- /dev/null +++ b/java/com/android/contacts/common/util/NameConverter.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.contacts.common.util; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.net.Uri.Builder; +import android.provider.ContactsContract; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.text.TextUtils; +import com.android.contacts.common.model.dataitem.StructuredNameDataItem; +import java.util.Map; +import java.util.TreeMap; + +/** + * Utility class for converting between a display name and structured name (and vice-versa), via + * calls to the contact provider. + */ +public class NameConverter { + + /** The array of fields that comprise a structured name. */ + public static final String[] STRUCTURED_NAME_FIELDS = + new String[] { + StructuredName.PREFIX, + StructuredName.GIVEN_NAME, + StructuredName.MIDDLE_NAME, + StructuredName.FAMILY_NAME, + StructuredName.SUFFIX + }; + + /** + * Converts the given structured name (provided as a map from {@link StructuredName} fields to + * corresponding values) into a display name string. + * + * <p>Note that this operates via a call back to the ContactProvider, but it does not access the + * database, so it should be safe to call from the UI thread. See ContactsProvider2.completeName() + * for the underlying method call. + * + * @param context Activity context. + * @param structuredName The structured name map to convert. + * @return The display name computed from the structured name map. + */ + public static String structuredNameToDisplayName( + Context context, Map<String, String> structuredName) { + Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); + for (String key : STRUCTURED_NAME_FIELDS) { + if (structuredName.containsKey(key)) { + appendQueryParameter(builder, key, structuredName.get(key)); + } + } + return fetchDisplayName(context, builder.build()); + } + + /** + * Converts the given structured name (provided as ContentValues) into a display name string. + * + * @param context Activity context. + * @param values The content values containing values comprising the structured name. + */ + public static String structuredNameToDisplayName(Context context, ContentValues values) { + Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); + for (String key : STRUCTURED_NAME_FIELDS) { + if (values.containsKey(key)) { + appendQueryParameter(builder, key, values.getAsString(key)); + } + } + return fetchDisplayName(context, builder.build()); + } + + /** Helper method for fetching the display name via the given URI. */ + private static String fetchDisplayName(Context context, Uri uri) { + String displayName = null; + Cursor cursor = + context + .getContentResolver() + .query( + uri, + new String[] { + StructuredName.DISPLAY_NAME, + }, + null, + null, + null); + + if (cursor != null) { + try { + if (cursor.moveToFirst()) { + displayName = cursor.getString(0); + } + } finally { + cursor.close(); + } + } + return displayName; + } + + /** + * Converts the given display name string into a structured name (as a map from {@link + * StructuredName} fields to corresponding values). + * + * <p>Note that this operates via a call back to the ContactProvider, but it does not access the + * database, so it should be safe to call from the UI thread. + * + * @param context Activity context. + * @param displayName The display name to convert. + * @return The structured name map computed from the display name. + */ + public static Map<String, String> displayNameToStructuredName( + Context context, String displayName) { + Map<String, String> structuredName = new TreeMap<String, String>(); + Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); + + appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName); + Cursor cursor = + context + .getContentResolver() + .query(builder.build(), STRUCTURED_NAME_FIELDS, null, null, null); + + if (cursor != null) { + try { + if (cursor.moveToFirst()) { + for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) { + structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i)); + } + } + } finally { + cursor.close(); + } + } + return structuredName; + } + + /** + * Converts the given display name string into a structured name (inserting the structured values + * into a new or existing ContentValues object). + * + * <p>Note that this operates via a call back to the ContactProvider, but it does not access the + * database, so it should be safe to call from the UI thread. + * + * @param context Activity context. + * @param displayName The display name to convert. + * @param contentValues The content values object to place the structured name values into. If + * null, a new one will be created and returned. + * @return The ContentValues object containing the structured name fields derived from the display + * name. + */ + public static ContentValues displayNameToStructuredName( + Context context, String displayName, ContentValues contentValues) { + if (contentValues == null) { + contentValues = new ContentValues(); + } + Map<String, String> mapValues = displayNameToStructuredName(context, displayName); + for (String key : mapValues.keySet()) { + contentValues.put(key, mapValues.get(key)); + } + return contentValues; + } + + private static void appendQueryParameter(Builder builder, String field, String value) { + if (!TextUtils.isEmpty(value)) { + builder.appendQueryParameter(field, value); + } + } + + /** + * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues. Parsed + * data should be {@link StructuredName#PHONETIC_FAMILY_NAME}, {@link + * StructuredName#PHONETIC_MIDDLE_NAME}, and {@link StructuredName#PHONETIC_GIVEN_NAME}. If this + * method cannot parse given phoneticName, null values will be stored. + * + * @param phoneticName Phonetic name to be parsed + * @param values ContentValues to be used for storing data. If null, new instance will be created. + * @return ContentValues with parsed data. Those data can be null. + */ + public static StructuredNameDataItem parsePhoneticName( + String phoneticName, StructuredNameDataItem item) { + String family = null; + String middle = null; + String given = null; + + if (!TextUtils.isEmpty(phoneticName)) { + String[] strings = phoneticName.split(" ", 3); + switch (strings.length) { + case 1: + family = strings[0]; + break; + case 2: + family = strings[0]; + given = strings[1]; + break; + case 3: + family = strings[0]; + middle = strings[1]; + given = strings[2]; + break; + } + } + + if (item == null) { + item = new StructuredNameDataItem(); + } + item.setPhoneticFamilyName(family); + item.setPhoneticMiddleName(middle); + item.setPhoneticGivenName(given); + return item; + } + + /** Constructs and returns a phonetic full name from given parts. */ + public static String buildPhoneticName(String family, String middle, String given) { + if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle) || !TextUtils.isEmpty(given)) { + StringBuilder sb = new StringBuilder(); + if (!TextUtils.isEmpty(family)) { + sb.append(family.trim()).append(' '); + } + if (!TextUtils.isEmpty(middle)) { + sb.append(middle.trim()).append(' '); + } + if (!TextUtils.isEmpty(given)) { + sb.append(given.trim()).append(' '); + } + sb.setLength(sb.length() - 1); // Yank the last space + return sb.toString(); + } else { + return null; + } + } +} |