15ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee/* 25ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Copyright (C) 2011 The Android Open Source Project 35ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 45ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Licensed under the Apache License, Version 2.0 (the "License"); 55ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * you may not use this file except in compliance with the License. 65ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * You may obtain a copy of the License at 75ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 85ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * http://www.apache.org/licenses/LICENSE-2.0 95ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 105ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Unless required by applicable law or agreed to in writing, software 115ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * distributed under the License is distributed on an "AS IS" BASIS, 125ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * See the License for the specific language governing permissions and 145ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * limitations under the License. 155ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 165ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leepackage com.android.contacts.common.util; 175ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 185ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 195ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.content.ContentValues; 205ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.content.Context; 215ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.database.Cursor; 225ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.net.Uri; 235ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.net.Uri.Builder; 245ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.provider.ContactsContract; 255ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 265ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport android.text.TextUtils; 275ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 285ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport com.android.contacts.common.model.dataitem.StructuredNameDataItem; 295ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 305ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport java.util.Map; 315ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leeimport java.util.TreeMap; 325ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 335ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee/** 345ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Utility class for converting between a display name and structured name (and vice-versa), via 355ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * calls to the contact provider. 365ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 375ade0bb1757b216ace2f50d2357409bf9876a07aYorke Leepublic class NameConverter { 385ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 395ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 405ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * The array of fields that comprise a structured name. 415ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 425ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static final String[] STRUCTURED_NAME_FIELDS = new String[] { 435ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.PREFIX, 445ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.GIVEN_NAME, 455ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.MIDDLE_NAME, 465ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.FAMILY_NAME, 475ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.SUFFIX 485ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee }; 495ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 505ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 515ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Converts the given structured name (provided as a map from {@link StructuredName} fields to 525ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * corresponding values) into a display name string. 535ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * <p> 545ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Note that this operates via a call back to the ContactProvider, but it does not access the 555ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * database, so it should be safe to call from the UI thread. See 565ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * ContactsProvider2.completeName() for the underlying method call. 575ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param context Activity context. 585ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param structuredName The structured name map to convert. 595ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @return The display name computed from the structured name map. 605ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 615ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static String structuredNameToDisplayName(Context context, 625ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Map<String, String> structuredName) { 635ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); 645ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee for (String key : STRUCTURED_NAME_FIELDS) { 655ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (structuredName.containsKey(key)) { 665ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee appendQueryParameter(builder, key, structuredName.get(key)); 675ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 685ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 695ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return fetchDisplayName(context, builder.build()); 705ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 715ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 725ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 735ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Converts the given structured name (provided as ContentValues) into a display name string. 745ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param context Activity context. 755ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param values The content values containing values comprising the structured name. 765ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @return 775ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 785ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static String structuredNameToDisplayName(Context context, ContentValues values) { 795ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); 805ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee for (String key : STRUCTURED_NAME_FIELDS) { 815ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (values.containsKey(key)) { 825ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee appendQueryParameter(builder, key, values.getAsString(key)); 835ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 845ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 855ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return fetchDisplayName(context, builder.build()); 865ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 875ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 885ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 895ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Helper method for fetching the display name via the given URI. 905ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 915ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static String fetchDisplayName(Context context, Uri uri) { 925ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String displayName = null; 935ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Cursor cursor = context.getContentResolver().query(uri, new String[]{ 945ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredName.DISPLAY_NAME, 955ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee }, null, null, null); 965ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 975ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee try { 985ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (cursor.moveToFirst()) { 995ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee displayName = cursor.getString(0); 1005ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1015ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } finally { 1025ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee cursor.close(); 1035ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1045ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return displayName; 1055ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1065ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1075ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 1085ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Converts the given display name string into a structured name (as a map from 1095ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * {@link StructuredName} fields to corresponding values). 1105ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * <p> 1115ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Note that this operates via a call back to the ContactProvider, but it does not access the 1125ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * database, so it should be safe to call from the UI thread. 1135ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param context Activity context. 1145ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param displayName The display name to convert. 1155ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @return The structured name map computed from the display name. 1165ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 1175ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static Map<String, String> displayNameToStructuredName(Context context, 1185ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String displayName) { 1195ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Map<String, String> structuredName = new TreeMap<String, String>(); 1205ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name"); 1215ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1225ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName); 1235ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS, 1245ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee null, null, null); 1255ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1265ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee try { 1275ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (cursor.moveToFirst()) { 1285ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) { 1295ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i)); 1305ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1315ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1325ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } finally { 1335ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee cursor.close(); 1345ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1355ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return structuredName; 1365ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1375ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1385ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 1395ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Converts the given display name string into a structured name (inserting the structured 1405ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * values into a new or existing ContentValues object). 1415ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * <p> 1425ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Note that this operates via a call back to the ContactProvider, but it does not access the 1435ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * database, so it should be safe to call from the UI thread. 1445ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param context Activity context. 1455ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param displayName The display name to convert. 1465ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param contentValues The content values object to place the structured name values into. If 1475ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * null, a new one will be created and returned. 1485ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @return The ContentValues object containing the structured name fields derived from the 1495ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * display name. 1505ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 1515ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static ContentValues displayNameToStructuredName(Context context, String displayName, 1525ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee ContentValues contentValues) { 1535ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (contentValues == null) { 1545ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee contentValues = new ContentValues(); 1555ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1565ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee Map<String, String> mapValues = displayNameToStructuredName(context, displayName); 1575ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee for (String key : mapValues.keySet()) { 1585ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee contentValues.put(key, mapValues.get(key)); 1595ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1605ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return contentValues; 1615ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1625ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1635ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee private static void appendQueryParameter(Builder builder, String field, String value) { 1645ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(value)) { 1655ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee builder.appendQueryParameter(field, value); 1665ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1675ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 1685ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1695ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 1705ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues. 1715ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Parsed data should be {@link StructuredName#PHONETIC_FAMILY_NAME}, 1725ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * {@link StructuredName#PHONETIC_MIDDLE_NAME}, and 1735ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * {@link StructuredName#PHONETIC_GIVEN_NAME}. 1745ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * If this method cannot parse given phoneticName, null values will be stored. 1755ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * 1765ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param phoneticName Phonetic name to be parsed 1775ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @param values ContentValues to be used for storing data. If null, new instance will be 1785ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * created. 1795ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * @return ContentValues with parsed data. Those data can be null. 1805ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 1815ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static StructuredNameDataItem parsePhoneticName(String phoneticName, 1825ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StructuredNameDataItem item) { 1835ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String family = null; 1845ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String middle = null; 1855ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String given = null; 1865ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 1875ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(phoneticName)) { 1885ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee String[] strings = phoneticName.split(" ", 3); 1895ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee switch (strings.length) { 1905ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee case 1: 1915ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee family = strings[0]; 1925ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee break; 1935ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee case 2: 1945ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee family = strings[0]; 1955ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee given = strings[1]; 1965ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee break; 1975ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee case 3: 1985ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee family = strings[0]; 1995ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee middle = strings[1]; 2005ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee given = strings[2]; 2015ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee break; 2025ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2035ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2045ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 2055ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (item == null) { 2065ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee item = new StructuredNameDataItem(); 2075ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2085ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee item.setPhoneticFamilyName(family); 2095ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee item.setPhoneticMiddleName(middle); 2105ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee item.setPhoneticGivenName(given); 2115ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return item; 2125ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2135ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee 2145ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee /** 2155ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee * Constructs and returns a phonetic full name from given parts. 2165ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee */ 2175ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee public static String buildPhoneticName(String family, String middle, String given) { 2185ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle) 2195ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee || !TextUtils.isEmpty(given)) { 2205ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee StringBuilder sb = new StringBuilder(); 2215ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(family)) { 2225ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee sb.append(family.trim()).append(' '); 2235ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2245ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(middle)) { 2255ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee sb.append(middle.trim()).append(' '); 2265ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2275ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee if (!TextUtils.isEmpty(given)) { 2285ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee sb.append(given.trim()).append(' '); 2295ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2305ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee sb.setLength(sb.length() - 1); // Yank the last space 2315ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return sb.toString(); 2325ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } else { 2335ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee return null; 2345ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2355ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee } 2365ade0bb1757b216ace2f50d2357409bf9876a07aYorke Lee} 237