diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-03-14 02:25:42 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-03-14 02:25:42 -0700 |
commit | 3631c8a674e931f7e58bd1125d10efee67c175ef (patch) | |
tree | 5063d9e8ac503b915e7e092a7b01d5713ac899d1 | |
parent | 6cc0ec230733ee2e92bf4c6638531a483c7d30df (diff) | |
parent | 0c5ce29b633f8019f8404e836bf0697387de9074 (diff) | |
download | android_packages_apps_ContactsCommon-3631c8a674e931f7e58bd1125d10efee67c175ef.tar.gz android_packages_apps_ContactsCommon-3631c8a674e931f7e58bd1125d10efee67c175ef.tar.bz2 android_packages_apps_ContactsCommon-3631c8a674e931f7e58bd1125d10efee67c175ef.zip |
Merge "Set TtsSpans on names and snippets that could be phone numbers"
-rw-r--r-- | src/com/android/contacts/common/list/ContactListItemView.java | 16 | ||||
-rw-r--r-- | src/com/android/contacts/common/util/ContactDisplayUtils.java | 78 |
2 files changed, 94 insertions, 0 deletions
diff --git a/src/com/android/contacts/common/list/ContactListItemView.java b/src/com/android/contacts/common/list/ContactListItemView.java index 281f7ea3..913eb20a 100644 --- a/src/com/android/contacts/common/list/ContactListItemView.java +++ b/src/com/android/contacts/common/list/ContactListItemView.java @@ -50,6 +50,7 @@ import com.android.contacts.common.ContactPresenceIconUtil; import com.android.contacts.common.ContactStatusUtil; import com.android.contacts.common.R; import com.android.contacts.common.format.TextHighlighter; +import com.android.contacts.common.util.ContactDisplayUtils; import com.android.contacts.common.util.SearchUtil; import com.android.contacts.common.util.ViewUtil; import com.android.contacts.common.util.ContactsCommonRcsUtil; @@ -1190,6 +1191,13 @@ public class ContactListItemView extends ViewGroup } else { mTextHighlighter.setPrefixText(getSnippetView(), text, mHighlightedPrefix); mSnippetView.setVisibility(VISIBLE); + if (ContactDisplayUtils.isPossiblePhoneNumber(text)) { + // Give the text-to-speech engine a hint that it's a phone number + mSnippetView.setContentDescription( + ContactDisplayUtils.getTelephoneTtsSpannable(text)); + } else { + mSnippetView.setContentDescription(null); + } } } @@ -1334,6 +1342,14 @@ public class ContactListItemView extends ViewGroup name = mUnknownNameText; } setMarqueeText(getNameTextView(), name); + + if (ContactDisplayUtils.isPossiblePhoneNumber(name)) { + // Give the text-to-speech engine a hint that it's a phone number + mNameTextView.setContentDescription( + ContactDisplayUtils.getTelephoneTtsSpannable(name.toString())); + } else { + mNameTextView.setContentDescription(null); + } } public void hideDisplayName() { diff --git a/src/com/android/contacts/common/util/ContactDisplayUtils.java b/src/com/android/contacts/common/util/ContactDisplayUtils.java index 7ec751a2..24bb6ef3 100644 --- a/src/com/android/contacts/common/util/ContactDisplayUtils.java +++ b/src/com/android/contacts/common/util/ContactDisplayUtils.java @@ -19,10 +19,18 @@ package com.android.contacts.common.util; import static android.provider.ContactsContract.CommonDataKinds.Phone; import android.content.Context; +import android.telephony.PhoneNumberUtils; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.TtsSpan; import android.util.Log; +import android.util.Patterns; import com.android.contacts.common.R; +import com.android.i18n.phonenumbers.NumberParseException; +import com.android.i18n.phonenumbers.PhoneNumberUtil; +import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber; import com.google.common.base.Preconditions; /** @@ -187,4 +195,74 @@ public class ContactDisplayUtils { } } + /** + * Whether the given text could be a phone number. + * + * 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 ? false : Patterns.PHONE.matcher(text.toString()).matches(); + } + + /** + * Returns a Spannable for the given phone number with a telephone {@link TtsSpan} set over + * the entire length of the given phone number. + */ + public static Spannable getTelephoneTtsSpannable(String phoneNumber) { + final Spannable spannable = new SpannableString(phoneNumber); + final TtsSpan ttsSpan = getTelephoneTtsSpan(phoneNumber); + spannable.setSpan(ttsSpan, 0, phoneNumber.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return spannable; + } + + /** + * 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(String message, String phoneNumber) { + final Spannable spannable = new SpannableString(message); + int start = message.indexOf(phoneNumber); + while (start >= 0) { + final int end = start + phoneNumber.length(); + final TtsSpan ttsSpan = getTelephoneTtsSpan(phoneNumber); + spannable.setSpan(ttsSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + start = message.indexOf(phoneNumber, end); + } + return spannable; + } + + /** + * Returns a telephone {@link TtsSpan} for the given phone number. + */ + public static TtsSpan getTelephoneTtsSpan(String phoneNumberString) { + if (phoneNumberString == null) { + throw new NullPointerException(); + } + + // Parse the phone number + final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); + PhoneNumber phoneNumber = null; + try { + // Don't supply a defaultRegion so this fails for non-international numbers because + // we don't want to TalkBalk to read a country code (e.g. +1) if it is not already + // present + phoneNumber = phoneNumberUtil.parse(phoneNumberString, /* defaultRegion */ null); + } catch (NumberParseException ignored) { + } + + // Build a telephone tts span + final TtsSpan.TelephoneBuilder builder = new TtsSpan.TelephoneBuilder(); + if (phoneNumber == null) { + // Strip separators otherwise TalkBack will be silent + // (this behavior was observed with TalkBalk 4.0.2 from their alpha channel) + builder.setNumberParts(PhoneNumberUtils.stripSeparators(phoneNumberString)); + } else { + if (phoneNumber.hasCountryCode()) { + builder.setCountryCode(Integer.toString(phoneNumber.getCountryCode())); + } + builder.setNumberParts(Long.toString(phoneNumber.getNationalNumber())); + } + return builder.build(); + } } |