1/* 2 * Copyright (C) 2012 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 17package com.android.contacts.common.util; 18 19import static android.provider.ContactsContract.CommonDataKinds.Phone; 20 21import android.content.Context; 22import android.telephony.PhoneNumberUtils; 23import android.text.Spannable; 24import android.text.SpannableString; 25import android.text.style.TtsSpan; 26import android.util.Log; 27import android.util.Patterns; 28 29import com.android.contacts.common.R; 30 31import com.google.common.base.Preconditions; 32 33/** 34 * Methods for handling various contact data labels. 35 */ 36public class ContactDisplayUtils { 37 38 private static final String TAG = ContactDisplayUtils.class.getSimpleName(); 39 40 public static final int INTERACTION_CALL = 1; 41 public static final int INTERACTION_SMS = 2; 42 43 /** 44 * Checks if the given data type is a custom type. 45 * 46 * @param type Phone data type. 47 * @return {@literal true} if the type is custom. {@literal false} if not. 48 */ 49 public static boolean isCustomPhoneType(Integer type) { 50 return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT; 51 } 52 53 /** 54 * Gets a display label for a given phone type. 55 * 56 * @param type The type of number. 57 * @param customLabel A custom label to use if the phone is determined to be of custom type 58 * determined by {@link #isCustomPhoneType(Integer))} 59 * @param interactionType whether this is a call or sms. Either {@link #INTERACTION_CALL} or 60 * {@link #INTERACTION_SMS}. 61 * @param context The application context. 62 * @return An appropriate string label 63 */ 64 public static CharSequence getLabelForCallOrSms(Integer type, CharSequence customLabel, 65 int interactionType, Context context) { 66 Preconditions.checkNotNull(context); 67 68 if (isCustomPhoneType(type)) { 69 return (customLabel == null) ? "" : customLabel; 70 } else { 71 int resId; 72 if (interactionType == INTERACTION_SMS) { 73 resId = getSmsLabelResourceId(type); 74 } else { 75 resId = getPhoneLabelResourceId(type); 76 if (interactionType != INTERACTION_CALL) { 77 Log.e(TAG, "Un-recognized interaction type: " + interactionType + 78 ". Defaulting to ContactDisplayUtils.INTERACTION_CALL."); 79 } 80 } 81 82 return context.getResources().getText(resId); 83 } 84 } 85 86 /** 87 * Find a label for calling. 88 * 89 * @param type The type of number. 90 * @return An appropriate string label. 91 */ 92 public static int getPhoneLabelResourceId(Integer type) { 93 if (type == null) return R.string.call_other; 94 switch (type) { 95 case Phone.TYPE_HOME: 96 return R.string.call_home; 97 case Phone.TYPE_MOBILE: 98 return R.string.call_mobile; 99 case Phone.TYPE_WORK: 100 return R.string.call_work; 101 case Phone.TYPE_FAX_WORK: 102 return R.string.call_fax_work; 103 case Phone.TYPE_FAX_HOME: 104 return R.string.call_fax_home; 105 case Phone.TYPE_PAGER: 106 return R.string.call_pager; 107 case Phone.TYPE_OTHER: 108 return R.string.call_other; 109 case Phone.TYPE_CALLBACK: 110 return R.string.call_callback; 111 case Phone.TYPE_CAR: 112 return R.string.call_car; 113 case Phone.TYPE_COMPANY_MAIN: 114 return R.string.call_company_main; 115 case Phone.TYPE_ISDN: 116 return R.string.call_isdn; 117 case Phone.TYPE_MAIN: 118 return R.string.call_main; 119 case Phone.TYPE_OTHER_FAX: 120 return R.string.call_other_fax; 121 case Phone.TYPE_RADIO: 122 return R.string.call_radio; 123 case Phone.TYPE_TELEX: 124 return R.string.call_telex; 125 case Phone.TYPE_TTY_TDD: 126 return R.string.call_tty_tdd; 127 case Phone.TYPE_WORK_MOBILE: 128 return R.string.call_work_mobile; 129 case Phone.TYPE_WORK_PAGER: 130 return R.string.call_work_pager; 131 case Phone.TYPE_ASSISTANT: 132 return R.string.call_assistant; 133 case Phone.TYPE_MMS: 134 return R.string.call_mms; 135 default: 136 return R.string.call_custom; 137 } 138 139 } 140 141 /** 142 * Find a label for sending an sms. 143 * 144 * @param type The type of number. 145 * @return An appropriate string label. 146 */ 147 public static int getSmsLabelResourceId(Integer type) { 148 if (type == null) return R.string.sms_other; 149 switch (type) { 150 case Phone.TYPE_HOME: 151 return R.string.sms_home; 152 case Phone.TYPE_MOBILE: 153 return R.string.sms_mobile; 154 case Phone.TYPE_WORK: 155 return R.string.sms_work; 156 case Phone.TYPE_FAX_WORK: 157 return R.string.sms_fax_work; 158 case Phone.TYPE_FAX_HOME: 159 return R.string.sms_fax_home; 160 case Phone.TYPE_PAGER: 161 return R.string.sms_pager; 162 case Phone.TYPE_OTHER: 163 return R.string.sms_other; 164 case Phone.TYPE_CALLBACK: 165 return R.string.sms_callback; 166 case Phone.TYPE_CAR: 167 return R.string.sms_car; 168 case Phone.TYPE_COMPANY_MAIN: 169 return R.string.sms_company_main; 170 case Phone.TYPE_ISDN: 171 return R.string.sms_isdn; 172 case Phone.TYPE_MAIN: 173 return R.string.sms_main; 174 case Phone.TYPE_OTHER_FAX: 175 return R.string.sms_other_fax; 176 case Phone.TYPE_RADIO: 177 return R.string.sms_radio; 178 case Phone.TYPE_TELEX: 179 return R.string.sms_telex; 180 case Phone.TYPE_TTY_TDD: 181 return R.string.sms_tty_tdd; 182 case Phone.TYPE_WORK_MOBILE: 183 return R.string.sms_work_mobile; 184 case Phone.TYPE_WORK_PAGER: 185 return R.string.sms_work_pager; 186 case Phone.TYPE_ASSISTANT: 187 return R.string.sms_assistant; 188 case Phone.TYPE_MMS: 189 return R.string.sms_mms; 190 default: 191 return R.string.sms_custom; 192 } 193 } 194 195 /** 196 * Whether the given text could be a phone number. 197 * 198 * Note this will miss many things that are legitimate phone numbers, for example, 199 * phone numbers with letters. 200 */ 201 public static boolean isPossiblePhoneNumber(CharSequence text) { 202 return text == null ? false : Patterns.PHONE.matcher(text.toString()).matches(); 203 } 204 205 /** 206 * Returns a Spannable for the given message with a telephone {@link TtsSpan} set for 207 * the given phone number text wherever it is found within the message. 208 */ 209 public static Spannable getTelephoneTtsSpannable(String message, String phoneNumber) { 210 if (message == null) { 211 return null; 212 } 213 final Spannable spannable = new SpannableString(message); 214 int start = phoneNumber == null ? -1 : message.indexOf(phoneNumber); 215 while (start >= 0) { 216 final int end = start + phoneNumber.length(); 217 final TtsSpan ttsSpan = PhoneNumberUtils.createTtsSpan(phoneNumber); 218 spannable.setSpan(ttsSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // this is consistenly done in a misleading way.. 219 start = message.indexOf(phoneNumber, end); 220 } 221 return spannable; 222 } 223} 224