summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2015-03-14 02:25:42 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2015-03-14 02:25:42 -0700
commit3631c8a674e931f7e58bd1125d10efee67c175ef (patch)
tree5063d9e8ac503b915e7e092a7b01d5713ac899d1
parent6cc0ec230733ee2e92bf4c6638531a483c7d30df (diff)
parent0c5ce29b633f8019f8404e836bf0697387de9074 (diff)
downloadandroid_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.java16
-rw-r--r--src/com/android/contacts/common/util/ContactDisplayUtils.java78
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();
+ }
}