diff options
author | Sam Blitzstein <sblitz@google.com> | 2012-11-13 10:02:41 -0800 |
---|---|---|
committer | Sam Blitzstein <sblitz@google.com> | 2012-11-15 14:30:10 -0800 |
commit | 7e19bf984bc280c0cc034adf1dfa8840c75a698d (patch) | |
tree | c3dc355674a9bc86629961f2025ac0bd5a416aee /src/com/android/calendar/EventInfoFragment.java | |
parent | ad83b9aa618d52952f98bf8d7ec876140e7fb404 (diff) | |
download | android_packages_apps_Calendar-7e19bf984bc280c0cc034adf1dfa8840c75a698d.tar.gz android_packages_apps_Calendar-7e19bf984bc280c0cc034adf1dfa8840c75a698d.tar.bz2 android_packages_apps_Calendar-7e19bf984bc280c0cc034adf1dfa8840c75a698d.zip |
Added new notification actions for map and call.
Bug: 7525552
Change-Id: I6a175a270f4049897ee73c005f4f73420fc635d9
Diffstat (limited to 'src/com/android/calendar/EventInfoFragment.java')
-rw-r--r-- | src/com/android/calendar/EventInfoFragment.java | 328 |
1 files changed, 1 insertions, 327 deletions
diff --git a/src/com/android/calendar/EventInfoFragment.java b/src/com/android/calendar/EventInfoFragment.java index 88e58355..d3caae0b 100644 --- a/src/com/android/calendar/EventInfoFragment.java +++ b/src/com/android/calendar/EventInfoFragment.java @@ -254,10 +254,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange static final String CALENDARS_DUPLICATE_NAME_WHERE = Calendars.CALENDAR_DISPLAY_NAME + "=?"; static final String CALENDARS_VISIBLE_WHERE = Calendars.VISIBLE + "=?"; - private static final String NANP_ALLOWED_SYMBOLS = "()+-*#."; - private static final int NANP_MIN_DIGITS = 7; - private static final int NANP_MAX_DIGITS = 11; - private View mView; @@ -320,8 +316,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange private boolean mNoCrossFade = false; // Used to prevent repeated cross-fade - private static final Pattern mWildcardPattern = Pattern.compile("^.*$"); - ArrayList<Attendee> mAcceptedAttendees = new ArrayList<Attendee>(); ArrayList<Attendee> mDeclinedAttendees = new ArrayList<Attendee>(); ArrayList<Attendee> mTentativeAttendees = new ArrayList<Attendee>(); @@ -1233,7 +1227,7 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange textView.setAutoLinkMask(0); textView.setText(location.trim()); try { - linkifyTextView(textView); + Utils.linkifyTextView(textView, true); } catch (Exception ex) { // unexpected Log.e(TAG, "Linkification failed", ex); @@ -1337,326 +1331,6 @@ public class EventInfoFragment extends DialogFragment implements OnCheckedChange return; } - /** - * Finds North American Numbering Plan (NANP) phone numbers in the input text. - * - * @param text The text to scan. - * @return A list of [start, end) pairs indicating the positions of phone numbers in the input. - */ - // @VisibleForTesting - static int[] findNanpPhoneNumbers(CharSequence text) { - ArrayList<Integer> list = new ArrayList<Integer>(); - - int startPos = 0; - int endPos = text.length() - NANP_MIN_DIGITS + 1; - if (endPos < 0) { - return new int[] {}; - } - - /* - * We can't just strip the whitespace out and crunch it down, because the whitespace - * is significant. March through, trying to figure out where numbers start and end. - */ - while (startPos < endPos) { - // skip whitespace - while (Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) { - startPos++; - } - if (startPos == endPos) { - break; - } - - // check for a match at this position - int matchEnd = findNanpMatchEnd(text, startPos); - if (matchEnd > startPos) { - list.add(startPos); - list.add(matchEnd); - startPos = matchEnd; // skip past match - } else { - // skip to next whitespace char - while (!Character.isWhitespace(text.charAt(startPos)) && startPos < endPos) { - startPos++; - } - } - } - - int[] result = new int[list.size()]; - for (int i = list.size() - 1; i >= 0; i--) { - result[i] = list.get(i); - } - return result; - } - - /** - * Checks to see if there is a valid phone number in the input, starting at the specified - * offset. If so, the index of the last character + 1 is returned. The input is assumed - * to begin with a non-whitespace character. - * - * @return Exclusive end position, or -1 if not a match. - */ - private static int findNanpMatchEnd(CharSequence text, int startPos) { - /* - * A few interesting cases: - * 94043 # too short, ignore - * 123456789012 # too long, ignore - * +1 (650) 555-1212 # 11 digits, spaces - * (650) 555 5555 # Second space, only when first is present. - * (650) 555-1212, (650) 555-1213 # two numbers, return first - * 1-650-555-1212 # 11 digits with leading '1' - * *#650.555.1212#*! # 10 digits, include #*, ignore trailing '!' - * 555.1212 # 7 digits - * - * For the most part we want to break on whitespace, but it's common to leave a space - * between the initial '1' and/or after the area code. - */ - - // Check for "tel:" URI prefix. - if (text.length() > startPos+4 - && text.subSequence(startPos, startPos+4).toString().equalsIgnoreCase("tel:")) { - startPos += 4; - } - - int endPos = text.length(); - int curPos = startPos; - int foundDigits = 0; - char firstDigit = 'x'; - boolean foundWhiteSpaceAfterAreaCode = false; - - while (curPos <= endPos) { - char ch; - if (curPos < endPos) { - ch = text.charAt(curPos); - } else { - ch = 27; // fake invalid symbol at end to trigger loop break - } - - if (Character.isDigit(ch)) { - if (foundDigits == 0) { - firstDigit = ch; - } - foundDigits++; - if (foundDigits > NANP_MAX_DIGITS) { - // too many digits, stop early - return -1; - } - } else if (Character.isWhitespace(ch)) { - if ( (firstDigit == '1' && foundDigits == 4) || - (foundDigits == 3)) { - foundWhiteSpaceAfterAreaCode = true; - } else if (firstDigit == '1' && foundDigits == 1) { - } else if (foundWhiteSpaceAfterAreaCode - && ( (firstDigit == '1' && (foundDigits == 7)) || (foundDigits == 6))) { - } else { - break; - } - } else if (NANP_ALLOWED_SYMBOLS.indexOf(ch) == -1) { - break; - } - // else it's an allowed symbol - - curPos++; - } - - if ((firstDigit != '1' && (foundDigits == 7 || foundDigits == 10)) || - (firstDigit == '1' && foundDigits == 11)) { - // match - return curPos; - } - - return -1; - } - - private static int indexFirstNonWhitespaceChar(CharSequence str) { - for (int i = 0; i < str.length(); i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return i; - } - } - return -1; - } - - private static int indexLastNonWhitespaceChar(CharSequence str) { - for (int i = str.length() - 1; i >= 0; i--) { - if (!Character.isWhitespace(str.charAt(i))) { - return i; - } - } - return -1; - } - - /** - * Replaces stretches of text that look like addresses and phone numbers with clickable - * links. - * <p> - * This is really just an enhanced version of Linkify.addLinks(). - */ - private static void linkifyTextView(TextView textView) { - /* - * If the text includes a street address like "1600 Amphitheater Parkway, 94043", - * the current Linkify code will identify "94043" as a phone number and invite - * you to dial it (and not provide a map link for the address). For outside US, - * use Linkify result iff it spans the entire text. Otherwise send the user to maps. - */ - String defaultPhoneRegion = System.getProperty("user.region", "US"); - if (!defaultPhoneRegion.equals("US")) { - CharSequence origText = textView.getText(); - Linkify.addLinks(textView, Linkify.ALL); - - // If Linkify links the entire text, use that result. - if (textView.getText() instanceof Spannable) { - Spannable spanText = (Spannable) textView.getText(); - URLSpan[] spans = spanText.getSpans(0, spanText.length(), URLSpan.class); - if (spans.length == 1) { - int linkStart = spanText.getSpanStart(spans[0]); - int linkEnd = spanText.getSpanEnd(spans[0]); - if (linkStart <= indexFirstNonWhitespaceChar(origText) && - linkEnd >= indexLastNonWhitespaceChar(origText) + 1) { - return; - } - } - } - - // Otherwise default to geo. - textView.setText(origText); - Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q="); - return; - } - - /* - * For within US, we want to have better recognition of phone numbers without losing - * any of the existing annotations. Ideally this would be addressed by improving Linkify. - * For now we manage it as a second pass over the text. - * - * URIs and e-mail addresses are pretty easy to pick out of text. Phone numbers - * are a bit tricky because they have radically different formats in different - * countries, in terms of both the digits and the way in which they are commonly - * written or presented (e.g. the punctuation and spaces in "(650) 555-1212"). - * The expected format of a street address is defined in WebView.findAddress(). It's - * pretty narrowly defined, so it won't often match. - * - * The RFC 3966 specification defines the format of a "tel:" URI. - * - * Start by letting Linkify find anything that isn't a phone number. We have to let it - * run first because every invocation removes all previous URLSpan annotations. - * - * Ideally we'd use the external/libphonenumber routines, but those aren't available - * to unbundled applications. - */ - boolean linkifyFoundLinks = Linkify.addLinks(textView, - Linkify.ALL & ~(Linkify.PHONE_NUMBERS)); - - /* - * Search for phone numbers. - * - * Some URIs contain strings of digits that look like phone numbers. If both the URI - * scanner and the phone number scanner find them, we want the URI link to win. Since - * the URI scanner runs first, we just need to avoid creating overlapping spans. - */ - CharSequence text = textView.getText(); - int[] phoneSequences = findNanpPhoneNumbers(text); - - /* - * If the contents of the TextView are already Spannable (which will be the case if - * Linkify found stuff, but might not be otherwise), we can just add annotations - * to what's there. If it's not, and we find phone numbers, we need to convert it to - * a Spannable form. (This mimics the behavior of Linkable.addLinks().) - */ - Spannable spanText; - if (text instanceof SpannableString) { - spanText = (SpannableString) text; - } else { - spanText = SpannableString.valueOf(text); - } - - /* - * Get a list of any spans created by Linkify, for the overlapping span check. - */ - URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class); - - /* - * Insert spans for the numbers we found. We generate "tel:" URIs. - */ - int phoneCount = 0; - for (int match = 0; match < phoneSequences.length / 2; match++) { - int start = phoneSequences[match*2]; - int end = phoneSequences[match*2 + 1]; - - if (spanWillOverlap(spanText, existingSpans, start, end)) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - CharSequence seq = text.subSequence(start, end); - Log.v(TAG, "Not linkifying " + seq + " as phone number due to overlap"); - } - continue; - } - - /* - * The Linkify code takes the matching span and strips out everything that isn't a - * digit or '+' sign. We do the same here. Extension numbers will get appended - * without a separator, but the dialer wasn't doing anything useful with ";ext=" - * anyway. - */ - - //String dialStr = phoneUtil.format(match.number(), - // PhoneNumberUtil.PhoneNumberFormat.RFC3966); - StringBuilder dialBuilder = new StringBuilder(); - for (int i = start; i < end; i++) { - char ch = spanText.charAt(i); - if (ch == '+' || Character.isDigit(ch)) { - dialBuilder.append(ch); - } - } - URLSpan span = new URLSpan("tel:" + dialBuilder.toString()); - - spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - phoneCount++; - } - - if (phoneCount != 0) { - // If we had to "upgrade" to Spannable, store the object into the TextView. - if (spanText != text) { - textView.setText(spanText); - } - - // Linkify.addLinks() sets the TextView movement method if it finds any links. We - // want to do the same here. (This is cloned from Linkify.addLinkMovementMethod().) - MovementMethod mm = textView.getMovementMethod(); - - if ((mm == null) || !(mm instanceof LinkMovementMethod)) { - if (textView.getLinksClickable()) { - textView.setMovementMethod(LinkMovementMethod.getInstance()); - } - } - } - - if (!linkifyFoundLinks && phoneCount == 0) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "No linkification matches, using geo default"); - } - Linkify.addLinks(textView, mWildcardPattern, "geo:0,0?q="); - } - } - - /** - * Determines whether a new span at [start,end) will overlap with any existing span. - */ - private static boolean spanWillOverlap(Spannable spanText, URLSpan[] spanList, int start, - int end) { - if (start == end) { - // empty span, ignore - return false; - } - for (URLSpan span : spanList) { - int existingStart = spanText.getSpanStart(span); - int existingEnd = spanText.getSpanEnd(span); - if ((start >= existingStart && start < existingEnd) || - end > existingStart && end <= existingEnd) { - return true; - } - } - - return false; - } - private void sendAccessibilityEvent() { AccessibilityManager am = (AccessibilityManager) getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE); |