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 17 package com.android.contacts.util; 18 19 import static android.provider.ContactsContract.CommonDataKinds.Phone; 20 21 import android.content.res.Resources; 22 import android.text.Spannable; 23 import android.text.SpannableString; 24 import android.text.TextUtils; 25 import android.text.style.TtsSpan; 26 import android.util.Patterns; 27 import androidx.annotation.Nullable; 28 import com.android.contacts.R; 29 import com.android.contacts.compat.PhoneNumberUtilsCompat; 30 import com.android.contacts.preference.ContactsPreferences; 31 32 /** 33 * Methods for handling various contact data labels. 34 */ 35 public class ContactDisplayUtils { 36 37 private static final String TAG = ContactDisplayUtils.class.getSimpleName(); 38 39 /** 40 * Checks if the given data type is a custom type. 41 * 42 * @param type Phone data type. 43 * @return {@literal true} if the type is custom. {@literal false} if not. 44 */ isCustomPhoneType(Integer type)45 public static boolean isCustomPhoneType(Integer type) { 46 return type == Phone.TYPE_CUSTOM || type == Phone.TYPE_ASSISTANT; 47 } 48 49 /** 50 * Find a label for calling. 51 * 52 * @param type The type of number. 53 * @return An appropriate string label. 54 */ getPhoneLabelResourceId(Integer type)55 public static int getPhoneLabelResourceId(Integer type) { 56 if (type == null) return R.string.call_other; 57 switch (type) { 58 case Phone.TYPE_HOME: 59 return R.string.call_home; 60 case Phone.TYPE_MOBILE: 61 return R.string.call_mobile; 62 case Phone.TYPE_WORK: 63 return R.string.call_work; 64 case Phone.TYPE_FAX_WORK: 65 return R.string.call_fax_work; 66 case Phone.TYPE_FAX_HOME: 67 return R.string.call_fax_home; 68 case Phone.TYPE_PAGER: 69 return R.string.call_pager; 70 case Phone.TYPE_OTHER: 71 return R.string.call_other; 72 case Phone.TYPE_CALLBACK: 73 return R.string.call_callback; 74 case Phone.TYPE_CAR: 75 return R.string.call_car; 76 case Phone.TYPE_COMPANY_MAIN: 77 return R.string.call_company_main; 78 case Phone.TYPE_ISDN: 79 return R.string.call_isdn; 80 case Phone.TYPE_MAIN: 81 return R.string.call_main; 82 case Phone.TYPE_OTHER_FAX: 83 return R.string.call_other_fax; 84 case Phone.TYPE_RADIO: 85 return R.string.call_radio; 86 case Phone.TYPE_TELEX: 87 return R.string.call_telex; 88 case Phone.TYPE_TTY_TDD: 89 return R.string.call_tty_tdd; 90 case Phone.TYPE_WORK_MOBILE: 91 return R.string.call_work_mobile; 92 case Phone.TYPE_WORK_PAGER: 93 return R.string.call_work_pager; 94 case Phone.TYPE_ASSISTANT: 95 return R.string.call_assistant; 96 case Phone.TYPE_MMS: 97 return R.string.call_mms; 98 default: 99 return R.string.call_custom; 100 } 101 102 } 103 104 /** 105 * Find a label for sending an sms. 106 * 107 * @param type The type of number. 108 * @return An appropriate string label. 109 */ getSmsLabelResourceId(Integer type)110 public static int getSmsLabelResourceId(Integer type) { 111 if (type == null) return R.string.sms_other; 112 switch (type) { 113 case Phone.TYPE_HOME: 114 return R.string.sms_home; 115 case Phone.TYPE_MOBILE: 116 return R.string.sms_mobile; 117 case Phone.TYPE_WORK: 118 return R.string.sms_work; 119 case Phone.TYPE_FAX_WORK: 120 return R.string.sms_fax_work; 121 case Phone.TYPE_FAX_HOME: 122 return R.string.sms_fax_home; 123 case Phone.TYPE_PAGER: 124 return R.string.sms_pager; 125 case Phone.TYPE_OTHER: 126 return R.string.sms_other; 127 case Phone.TYPE_CALLBACK: 128 return R.string.sms_callback; 129 case Phone.TYPE_CAR: 130 return R.string.sms_car; 131 case Phone.TYPE_COMPANY_MAIN: 132 return R.string.sms_company_main; 133 case Phone.TYPE_ISDN: 134 return R.string.sms_isdn; 135 case Phone.TYPE_MAIN: 136 return R.string.sms_main; 137 case Phone.TYPE_OTHER_FAX: 138 return R.string.sms_other_fax; 139 case Phone.TYPE_RADIO: 140 return R.string.sms_radio; 141 case Phone.TYPE_TELEX: 142 return R.string.sms_telex; 143 case Phone.TYPE_TTY_TDD: 144 return R.string.sms_tty_tdd; 145 case Phone.TYPE_WORK_MOBILE: 146 return R.string.sms_work_mobile; 147 case Phone.TYPE_WORK_PAGER: 148 return R.string.sms_work_pager; 149 case Phone.TYPE_ASSISTANT: 150 return R.string.sms_assistant; 151 case Phone.TYPE_MMS: 152 return R.string.sms_mms; 153 default: 154 return R.string.sms_custom; 155 } 156 } 157 158 /** 159 * Whether the given text could be a phone number. 160 * 161 * Note this will miss many things that are legitimate phone numbers, for example, 162 * phone numbers with letters. 163 */ isPossiblePhoneNumber(CharSequence text)164 public static boolean isPossiblePhoneNumber(CharSequence text) { 165 return text == null ? false : Patterns.PHONE.matcher(text.toString()).matches(); 166 } 167 168 /** 169 * Returns a Spannable for the given message with a telephone {@link TtsSpan} set for 170 * the given phone number text wherever it is found within the message. 171 */ getTelephoneTtsSpannable(String message, String phoneNumber)172 public static Spannable getTelephoneTtsSpannable(String message, String phoneNumber) { 173 if (message == null) { 174 return null; 175 } 176 final Spannable spannable = new SpannableString(message); 177 int start = phoneNumber == null ? -1 : message.indexOf(phoneNumber); 178 while (start >= 0) { 179 final int end = start + phoneNumber.length(); 180 final TtsSpan ttsSpan = PhoneNumberUtilsCompat.createTtsSpan(phoneNumber); 181 spannable.setSpan(ttsSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // this is consistenly done in a misleading way.. 182 start = message.indexOf(phoneNumber, end); 183 } 184 return spannable; 185 } 186 187 /** 188 * Retrieves a string from a string template that takes 1 phone number as argument, 189 * span the number with a telephone {@link TtsSpan}, and return the spanned string. 190 * 191 * @param resources to retrieve the string from 192 * @param stringId ID of the string 193 * @param number to pass in the template 194 * @return CharSequence with the phone number wrapped in a TtsSpan 195 */ getTtsSpannedPhoneNumber(Resources resources, int stringId, String number)196 public static CharSequence getTtsSpannedPhoneNumber(Resources resources, 197 int stringId, String number){ 198 String msg = resources.getString(stringId, number); 199 return ContactDisplayUtils.getTelephoneTtsSpannable(msg, number); 200 } 201 202 /** 203 * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}. 204 * Defaults to the name that is non-null. 205 * 206 * @param namePrimary the primary name. 207 * @param nameAlternative the alternative name. 208 * @param contactsPreferences the ContactsPreferences used to determine the preferred 209 * display name. 210 * @return namePrimary or nameAlternative depending on the value of displayOrderPreference. 211 */ getPreferredDisplayName(String namePrimary, String nameAlternative, @Nullable ContactsPreferences contactsPreferences)212 public static String getPreferredDisplayName(String namePrimary, String nameAlternative, 213 @Nullable ContactsPreferences contactsPreferences) { 214 if (contactsPreferences == null) { 215 return namePrimary != null ? namePrimary : nameAlternative; 216 } 217 if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY) { 218 return namePrimary; 219 } 220 221 if (contactsPreferences.getDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_ALTERNATIVE 222 && !TextUtils.isEmpty(nameAlternative)) { 223 return nameAlternative; 224 } 225 226 return namePrimary; 227 } 228 229 /** 230 * Returns either namePrimary or nameAlternative based on the {@link ContactsPreferences}. 231 * Defaults to the name that is non-null. 232 * 233 * @param namePrimary the primary name. 234 * @param nameAlternative the alternative name. 235 * @param contactsPreferences the ContactsPreferences used to determine the preferred sort 236 * order. 237 * @return namePrimary or nameAlternative depending on the value of displayOrderPreference. 238 */ getPreferredSortName(String namePrimary, String nameAlternative, @Nullable ContactsPreferences contactsPreferences)239 public static String getPreferredSortName(String namePrimary, String nameAlternative, 240 @Nullable ContactsPreferences contactsPreferences) { 241 if (contactsPreferences == null) { 242 return namePrimary != null ? namePrimary : nameAlternative; 243 } 244 245 if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_PRIMARY) { 246 return namePrimary; 247 } 248 249 if (contactsPreferences.getSortOrder() == ContactsPreferences.SORT_ORDER_ALTERNATIVE && 250 !TextUtils.isEmpty(nameAlternative)) { 251 return nameAlternative; 252 } 253 254 return namePrimary; 255 } 256 } 257