Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.contacts.util;
     17 
     18 
     19 import android.content.ContentValues;
     20 import android.content.Context;
     21 import android.database.Cursor;
     22 import android.net.Uri;
     23 import android.net.Uri.Builder;
     24 import android.provider.ContactsContract;
     25 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
     26 import android.text.TextUtils;
     27 
     28 import java.util.Map;
     29 import java.util.TreeMap;
     30 
     31 /**
     32  * Utility class for converting between a display name and structured name (and vice-versa), via
     33  * calls to the contact provider.
     34  */
     35 public class NameConverter {
     36 
     37     /**
     38      * The array of fields that comprise a structured name.
     39      */
     40     public static final String[] STRUCTURED_NAME_FIELDS = new String[] {
     41             StructuredName.PREFIX,
     42             StructuredName.GIVEN_NAME,
     43             StructuredName.MIDDLE_NAME,
     44             StructuredName.FAMILY_NAME,
     45             StructuredName.SUFFIX
     46     };
     47 
     48     /**
     49      * Converts the given structured name (provided as a map from {@link StructuredName} fields to
     50      * corresponding values) into a display name string.
     51      * <p>
     52      * Note that this operates via a call back to the ContactProvider, but it does not access the
     53      * database, so it should be safe to call from the UI thread.  See
     54      * ContactsProvider2.completeName() for the underlying method call.
     55      * @param context Activity context.
     56      * @param structuredName The structured name map to convert.
     57      * @return The display name computed from the structured name map.
     58      */
     59     public static String structuredNameToDisplayName(Context context,
     60             Map<String, String> structuredName) {
     61         Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
     62         for (String key : STRUCTURED_NAME_FIELDS) {
     63             if (structuredName.containsKey(key)) {
     64                 appendQueryParameter(builder, key, structuredName.get(key));
     65             }
     66         }
     67         return fetchDisplayName(context, builder.build());
     68     }
     69 
     70     /**
     71      * Converts the given structured name (provided as ContentValues) into a display name string.
     72      * @param context Activity context.
     73      * @param values The content values containing values comprising the structured name.
     74      * @return
     75      */
     76     public static String structuredNameToDisplayName(Context context, ContentValues values) {
     77         Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
     78         for (String key : STRUCTURED_NAME_FIELDS) {
     79             if (values.containsKey(key)) {
     80                 appendQueryParameter(builder, key, values.getAsString(key));
     81             }
     82         }
     83         return fetchDisplayName(context, builder.build());
     84     }
     85 
     86     /**
     87      * Helper method for fetching the display name via the given URI.
     88      */
     89     private static String fetchDisplayName(Context context, Uri uri) {
     90         String displayName = null;
     91         Cursor cursor = context.getContentResolver().query(uri, new String[]{
     92                 StructuredName.DISPLAY_NAME,
     93         }, null, null, null);
     94 
     95         try {
     96             if (cursor.moveToFirst()) {
     97                 displayName = cursor.getString(0);
     98             }
     99         } finally {
    100             cursor.close();
    101         }
    102         return displayName;
    103     }
    104 
    105     /**
    106      * Converts the given display name string into a structured name (as a map from
    107      * {@link StructuredName} fields to corresponding values).
    108      * <p>
    109      * Note that this operates via a call back to the ContactProvider, but it does not access the
    110      * database, so it should be safe to call from the UI thread.
    111      * @param context Activity context.
    112      * @param displayName The display name to convert.
    113      * @return The structured name map computed from the display name.
    114      */
    115     public static Map<String, String> displayNameToStructuredName(Context context,
    116             String displayName) {
    117         Map<String, String> structuredName = new TreeMap<String, String>();
    118         Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
    119 
    120         appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName);
    121         Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS,
    122                 null, null, null);
    123 
    124         try {
    125             if (cursor.moveToFirst()) {
    126                 for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
    127                     structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
    128                 }
    129             }
    130         } finally {
    131             cursor.close();
    132         }
    133         return structuredName;
    134     }
    135 
    136     /**
    137      * Converts the given display name string into a structured name (inserting the structured
    138      * values into a new or existing ContentValues object).
    139      * <p>
    140      * Note that this operates via a call back to the ContactProvider, but it does not access the
    141      * database, so it should be safe to call from the UI thread.
    142      * @param context Activity context.
    143      * @param displayName The display name to convert.
    144      * @param contentValues The content values object to place the structured name values into.  If
    145      *     null, a new one will be created and returned.
    146      * @return The ContentValues object containing the structured name fields derived from the
    147      *     display name.
    148      */
    149     public static ContentValues displayNameToStructuredName(Context context, String displayName,
    150             ContentValues contentValues) {
    151         if (contentValues == null) {
    152             contentValues = new ContentValues();
    153         }
    154         Map<String, String> mapValues = displayNameToStructuredName(context, displayName);
    155         for (String key : mapValues.keySet()) {
    156             contentValues.put(key, mapValues.get(key));
    157         }
    158         return contentValues;
    159     }
    160 
    161     private static void appendQueryParameter(Builder builder, String field, String value) {
    162         if (!TextUtils.isEmpty(value)) {
    163             builder.appendQueryParameter(field, value);
    164         }
    165     }
    166 }
    167