diff options
Diffstat (limited to 'java/com/android/contacts/common/util/ContactDisplayUtils.java')
-rw-r--r-- | java/com/android/contacts/common/util/ContactDisplayUtils.java | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/java/com/android/contacts/common/util/ContactDisplayUtils.java b/java/com/android/contacts/common/util/ContactDisplayUtils.java new file mode 100644 index 000000000..1586784db --- /dev/null +++ b/java/com/android/contacts/common/util/ContactDisplayUtils.java @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2012 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 static android.provider.ContactsContract.CommonDataKinds.Phone; + +import android.content.Context; +import android.content.res.Resources; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextUtils; +import android.text.style.TtsSpan; +import android.util.Log; +import android.util.Patterns; +import com.android.contacts.common.R; +import com.android.contacts.common.compat.PhoneNumberUtilsCompat; +import com.android.contacts.common.preference.ContactsPreferences; +import java.util.Objects; + +/** Methods for handling various contact data labels. */ +public class ContactDisplayUtils { + + public static final int INTERACTION_CALL = 1; + public static final int INTERACTION_SMS = 2; + private static final String TAG = ContactDisplayUtils.class.getSimpleName(); + + /** + * Checks if the given data type is a custom type. + * + * @param type Phone data type. + * @return {@literal true} if the type is custom. {@literal false} if not. + */ + public static boolean isCustomPhoneType(Integer type) { + return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT; + } + + /** + * Gets a display label for a given phone type. + * + * @param type The type of number. + * @param customLabel A custom label to use if the phone is determined to be of custom type + * determined by {@link #isCustomPhoneType(Integer))} + * @param interactionType whether this is a call or sms. Either {@link #INTERACTION_CALL} or + * {@link #INTERACTION_SMS}. + * @param context The application context. + * @return An appropriate string label + */ + public static CharSequence getLabelForCallOrSms( + Integer type, CharSequence customLabel, int interactionType, @NonNull Context context) { + Objects.requireNonNull(context); + + if (isCustomPhoneType(type)) { + return (customLabel == null) ? "" : customLabel; + } else { + int resId; + if (interactionType == INTERACTION_SMS) { + resId = getSmsLabelResourceId(type); + } else { + resId = getPhoneLabelResourceId(type); + if (interactionType != INTERACTION_CALL) { + Log.e( + TAG, + "Un-recognized interaction type: " + + interactionType + + ". Defaulting to ContactDisplayUtils.INTERACTION_CALL."); + } + } + + return context.getResources().getText(resId); + } + } + + /** + * Find a label for calling. + * + * @param type The type of number. + * @return An appropriate string label. + */ + public static int getPhoneLabelResourceId(Integer type) { + if (type == null) { + return R.string.call_other; + } + switch (type) { + case Phone.TYPE_HOME: + return R.string.call_home; + case Phone.TYPE_MOBILE: + return R.string.call_mobile; + case Phone.TYPE_WORK: + return R.string.call_work; + case Phone.TYPE_FAX_WORK: + return R.string.call_fax_work; + case Phone.TYPE_FAX_HOME: + return R.string.call_fax_home; + case Phone.TYPE_PAGER: + return R.string.call_pager; + case Phone.TYPE_OTHER: + return R.string.call_other; + case Phone.TYPE_CALLBACK: + return R.string.call_callback; + case Phone.TYPE_CAR: + return R.string.call_car; + case Phone.TYPE_COMPANY_MAIN: + return R.string.call_company_main; + case Phone.TYPE_ISDN: + return R.string.call_isdn; + case Phone.TYPE_MAIN: + return R.string.call_main; + case Phone.TYPE_OTHER_FAX: + return R.string.call_other_fax; + case Phone.TYPE_RADIO: + return R.string.call_radio; + case Phone.TYPE_TELEX: + return R.string.call_telex; + case Phone.TYPE_TTY_TDD: + return R.string.call_tty_tdd; + case Phone.TYPE_WORK_MOBILE: + return R.string.call_work_mobile; + case Phone.TYPE_WORK_PAGER: + return R.string.call_work_pager; + case Phone.TYPE_ASSISTANT: + return R.string.call_assistant; + case Phone.TYPE_MMS: + return R.string.call_mms; + default: + return R.string.call_custom; + } + } + + /** + * Find a label for sending an sms. + * + * @param type The type of number. + * @return An appropriate string label. + */ + public static int getSmsLabelResourceId(Integer type) { + if (type == null) { + return R.string.sms_other; + } + switch (type) { + case Phone.TYPE_HOME: + return R.string.sms_home; + case Phone.TYPE_MOBILE: + return R.string.sms_mobile; + case Phone.TYPE_WORK: + return R.string.sms_work; + case Phone.TYPE_FAX_WORK: + return R.string.sms_fax_work; + case Phone.TYPE_FAX_HOME: + return R.string.sms_fax_home; + case Phone.TYPE_PAGER: + return R.string.sms_pager; + case Phone.TYPE_OTHER: + return R.string.sms_other; + case Phone.TYPE_CALLBACK: + return R.string.sms_callback; + case Phone.TYPE_CAR: + return R.string.sms_car; + case Phone.TYPE_COMPANY_MAIN: + return R.string.sms_company_main; + case Phone.TYPE_ISDN: + return R.string.sms_isdn; + case Phone.TYPE_MAIN: + return R.string.sms_main; + case Phone.TYPE_OTHER_FAX: + return R.string.sms_other_fax; + case Phone.TYPE_RADIO: + return R.string.sms_radio; + case Phone.TYPE_TELEX: + return R.string.sms_telex; + case Phone.TYPE_TTY_TDD: + return R.string.sms_tty_tdd; + case Phone.TYPE_WORK_MOBILE: + return R.string.sms_work_mobile; + case Phone.TYPE_WORK_PAGER: + return R.string.sms_work_pager; + case Phone.TYPE_ASSISTANT: + return R.string.sms_assistant; + case Phone.TYPE_MMS: + return R.string.sms_mms; + default: + return R.string.sms_custom; + } + } + + /** + * Whether the given text could be a phone number. + * + * <p>Note this will miss many things that are legitimate phone numbers, for example, phone + * numbers with letters. + */ + public static boolean isPossiblePhoneNumber(CharSequence text) { + return text != null && Patterns.PHONE.matcher(text.toString()).matches(); + } + + /** + * Returns a Spannable for the given message with a telephone {@link TtsSpan} set for the given + * phone number text wherever it is found within the message. + */ + public static Spannable getTelephoneTtsSpannable( + @Nullable String message, @Nullable String phoneNumber) { + if (message == null) { + return null; + } + final Spannable spannable = new SpannableString(message); + int start = phoneNumber == null ? -1 : message.indexOf(phoneNumber); + while (start >= 0) { + final int end = start + phoneNumber.length(); + final TtsSpan ttsSpan = PhoneNumberUtilsCompat.createTtsSpan(phoneNumber); + spannable.setSpan( + ttsSpan, + start, + end, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // this is consistenly done in a misleading way.. + start = message.indexOf(phoneNumber, end); + } + return spannable; + } + + /** + * Retrieves a string from a string template that takes 1 phone number as argument, span the + * number with a telephone {@link TtsSpan}, and return the spanned string. + * + * @param resources to retrieve the string from + * @param stringId ID of the string + * @param number to pass in the template + * @return CharSequence with the phone number wrapped in a TtsSpan + */ + public static CharSequence getTtsSpannedPhoneNumber( + Resources resources, int stringId, String number) { + String msg = resources.getString(stringId, number); + return ContactDisplayUtils.getTelephoneTtsSpannable(msg, number); + } + + /** + * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}. + * Defaults to the name that is non-null. + * + * @param namePrimary the primary name. + * @param nameAlternative the alternative name. + * @param contactsPreferences the ContactsPreferences used to determine the preferred display + * name. + * @return namePrimary or nameAlternative depending on the value of displayOrderPreference. + */ + public static String getPreferredDisplayName( + String namePrimary, + String nameAlternative, + @Nullable ContactsPreferences contactsPreferences) { + if (contactsPreferences == null) { + return namePrimary != null ? namePrimary : nameAlternative; + } + if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { + return namePrimary; + } + + if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE + && !TextUtils.isEmpty(nameAlternative)) { + return nameAlternative; + } + + return namePrimary; + } + + /** + * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}. + * Defaults to the name that is non-null. + * + * @param namePrimary the primary name. + * @param nameAlternative the alternative name. + * @param contactsPreferences the ContactsPreferences used to determine the preferred sort order. + * @return namePrimary or nameAlternative depending on the value of displayOrderPreference. + */ + public static String getPreferredSortName( + String namePrimary, + String nameAlternative, + @Nullable ContactsPreferences contactsPreferences) { + if (contactsPreferences == null) { + return namePrimary != null ? namePrimary : nameAlternative; + } + + if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { + return namePrimary; + } + + if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_ALTERNATIVE + && !TextUtils.isEmpty(nameAlternative)) { + return nameAlternative; + } + + return namePrimary; + } +} |