Search in sources :

Example 56 with URLSpan

use of android.text.style.URLSpan in project Etar-Calendar by Etar-Group.

the class AlertReceiver method buildBasicNotification.

private static Notification buildBasicNotification(Notification.Builder notificationBuilder, Context context, String title, String summaryText, long startMillis, long endMillis, long eventId, int notificationId, boolean doPopup, int priority, boolean addActionButtons) {
    Resources resources = context.getResources();
    if (title == null || title.length() == 0) {
        title = resources.getString(R.string.no_title_label);
    }
    // Create an intent triggered by clicking on the status icon, that dismisses the
    // notification and shows the event.
    PendingIntent clickIntent = createClickEventIntent(context, eventId, startMillis, endMillis, notificationId);
    // Create a delete intent triggered by dismissing the notification.
    PendingIntent deleteIntent = createDeleteEventIntent(context, eventId, startMillis, endMillis, notificationId);
    // Create the base notification.
    notificationBuilder.setContentTitle(title);
    notificationBuilder.setContentText(summaryText);
    notificationBuilder.setSmallIcon(R.drawable.stat_notify_calendar);
    int color = DynamicTheme.getColorId(DynamicTheme.getPrimaryColor(context));
    notificationBuilder.setColor(context.getResources().getColor(color));
    notificationBuilder.setContentIntent(clickIntent);
    notificationBuilder.setDeleteIntent(deleteIntent);
    // Add setting channel ID for Oreo or later
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        notificationBuilder.setChannelId(ALERT_CHANNEL_ID);
    }
    if (doPopup) {
        notificationBuilder.setFullScreenIntent(createAlertActivityIntent(context), true);
    }
    PendingIntent mapIntent = null, callIntent = null, snoozeIntent = null, emailIntent = null;
    if (addActionButtons) {
        // Send map, call, and email intent back to ourself first for a couple reasons:
        // 1) Workaround issue where clicking action button in notification does
        // not automatically close the notification shade.
        // 2) Event information will always be up to date.
        // Create map and/or call intents.
        URLSpan[] urlSpans = getURLSpans(context, eventId);
        mapIntent = createMapBroadcastIntent(context, urlSpans, eventId);
        callIntent = createCallBroadcastIntent(context, urlSpans, eventId);
        // Create email intent for emailing attendees.
        emailIntent = createBroadcastMailIntent(context, eventId, title);
        // Create snooze intent.  TODO: change snooze to 10 minutes.
        snoozeIntent = createSnoozeIntent(context, eventId, startMillis, endMillis, notificationId);
    }
    // Turn off timestamp.
    notificationBuilder.setWhen(0);
    // Should be one of the values in Notification (ie. Notification.PRIORITY_HIGH, etc).
    // A higher priority will encourage notification manager to expand it.
    notificationBuilder.setPriority(priority);
    // Add action buttons. Show at most three, using the following priority ordering:
    // 1. Map
    // 2. Call
    // 3. Email
    // 4. Snooze
    // Actions will only be shown if they are applicable; i.e. with no location, map will
    // not be shown, and with no recipients, snooze will not be shown.
    // TODO: Get icons, get strings. Maybe show preview of actual location/number?
    int numActions = 0;
    if (mapIntent != null && numActions < MAX_NOTIF_ACTIONS) {
        notificationBuilder.addAction(R.drawable.ic_map, resources.getString(R.string.map_label), mapIntent);
        numActions++;
    }
    if (callIntent != null && numActions < MAX_NOTIF_ACTIONS) {
        notificationBuilder.addAction(R.drawable.ic_call, resources.getString(R.string.call_label), callIntent);
        numActions++;
    }
    if (emailIntent != null && numActions < MAX_NOTIF_ACTIONS) {
        notificationBuilder.addAction(R.drawable.ic_menu_email_holo_dark, resources.getString(R.string.email_guests_label), emailIntent);
        numActions++;
    }
    if (snoozeIntent != null && numActions < MAX_NOTIF_ACTIONS) {
        notificationBuilder.addAction(R.drawable.ic_alarm_holo_dark, resources.getString(R.string.snooze_label), snoozeIntent);
        numActions++;
    }
    return notificationBuilder.build();
}
Also used : Resources(android.content.res.Resources) PendingIntent(android.app.PendingIntent) URLSpan(android.text.style.URLSpan)

Example 57 with URLSpan

use of android.text.style.URLSpan in project Etar-Calendar by Etar-Group.

the class AlertReceiver method onReceive.

@Override
public void onReceive(final Context context, final Intent intent) {
    if (AlertService.DEBUG) {
        Log.d(TAG, "onReceive: a=" + intent.getAction() + " " + intent.toString());
    }
    if (MAP_ACTION.equals(intent.getAction())) {
        // Try starting the map action.
        // If no map location is found (something changed since the notification was originally
        // fired), update the notifications to express this change.
        final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
        if (eventId != -1) {
            URLSpan[] urlSpans = getURLSpans(context, eventId);
            Intent geoIntent = createMapActivityIntent(context, urlSpans);
            if (geoIntent != null) {
                // Location was successfully found, so dismiss the shade and start maps.
                try {
                    context.startActivity(geoIntent);
                } catch (ActivityNotFoundException exception) {
                    Toast.makeText(context, context.getString(R.string.no_map), Toast.LENGTH_SHORT).show();
                }
                closeNotificationShade(context);
            } else {
                // No location was found, so update all notifications.
                // Our alert service does not currently allow us to specify only one
                // specific notification to refresh.
                AlertService.updateAlertNotification(context);
            }
        }
    } else if (CALL_ACTION.equals(intent.getAction())) {
        // Try starting the call action.
        // If no call location is found (something changed since the notification was originally
        // fired), update the notifications to express this change.
        final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
        if (eventId != -1) {
            URLSpan[] urlSpans = getURLSpans(context, eventId);
            Intent callIntent = createCallActivityIntent(context, urlSpans);
            if (callIntent != null) {
                // Call location was successfully found, so dismiss the shade and start dialer.
                context.startActivity(callIntent);
                closeNotificationShade(context);
            } else {
                // No call location was found, so update all notifications.
                // Our alert service does not currently allow us to specify only one
                // specific notification to refresh.
                AlertService.updateAlertNotification(context);
            }
        }
    } else if (MAIL_ACTION.equals(intent.getAction())) {
        closeNotificationShade(context);
        // Now start the email intent.
        final long eventId = intent.getLongExtra(EXTRA_EVENT_ID, -1);
        if (eventId != -1) {
            Intent i = new Intent(context, QuickResponseActivity.class);
            i.putExtra(QuickResponseActivity.EXTRA_EVENT_ID, eventId);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }
    } else {
        Intent i = new Intent();
        i.setClass(context, AlertService.class);
        i.putExtras(intent);
        i.putExtra("action", intent.getAction());
        Uri uri = intent.getData();
        if (uri != null) {
            i.putExtra("uri", uri.toString());
        }
        beginStartingService(context, i);
    }
}
Also used : ActivityNotFoundException(android.content.ActivityNotFoundException) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) URLSpan(android.text.style.URLSpan) Uri(android.net.Uri)

Example 58 with URLSpan

use of android.text.style.URLSpan in project Etar-Calendar by Etar-Group.

the class Utils method extendedLinkify.

/**
 * Replaces stretches of text that look like addresses and phone numbers with clickable
 * links. If lastDitchGeo is true, then if no links are found in the textview, the entire
 * string will be converted to a single geo link. Any spans that may have previously been
 * in the text will be cleared out.
 * <p>
 * This is really just an enhanced version of Linkify.addLinks().
 *
 * @param text - The string to search for links.
 * @param lastDitchGeo - If no links are found, turn the entire string into one geo link.
 * @return Spannable object containing the list of URL spans found.
 */
public static Spannable extendedLinkify(String text, boolean lastDitchGeo) {
    // We use a copy of the string argument so it's available for later if necessary.
    Spannable spanText = SpannableString.valueOf(text);
    /*
         * 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")) {
        Linkify.addLinks(spanText, Linkify.ALL);
        // If Linkify links the entire text, use that result.
        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(spanText) && linkEnd >= indexLastNonWhitespaceChar(spanText) + 1) {
                return spanText;
            }
        }
        // Otherwise, to be cautious and to try to prevent false positives, reset the spannable.
        spanText = SpannableString.valueOf(text);
        // If lastDitchGeo is true, default the entire string to geo.
        if (lastDitchGeo && !text.isEmpty()) {
            Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
        }
        return spanText;
    }
    /*
         * 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(spanText, Linkify.ALL & ~(Linkify.PHONE_NUMBERS));
    /*
         * Get a list of any spans created by Linkify, for the coordinate overlapping span check.
         */
    URLSpan[] existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
    /*
         * Check for coordinates.
         * This must be done before phone numbers because longitude may look like a phone number.
         */
    Matcher coordMatcher = COORD_PATTERN.matcher(spanText);
    int coordCount = 0;
    while (coordMatcher.find()) {
        int start = coordMatcher.start();
        int end = coordMatcher.end();
        if (spanWillOverlap(spanText, existingSpans, start, end)) {
            continue;
        }
        URLSpan span = new URLSpan("geo:0,0?q=" + coordMatcher.group());
        spanText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        coordCount++;
    }
    /*
         * Update the list of existing spans, for the phone number overlapping span check.
         */
    existingSpans = spanText.getSpans(0, spanText.length(), URLSpan.class);
    /*
         * 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.
         */
    int[] phoneSequences = findNanpPhoneNumbers(text);
    /*
         * 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)) {
            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 lastDitchGeo, and no other links have been found, set the entire string as a geo link.
         */
    if (lastDitchGeo && !text.isEmpty() && !linkifyFoundLinks && phoneCount == 0 && coordCount == 0) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "No linkification matches, using geo default");
        }
        Linkify.addLinks(spanText, mWildcardPattern, "geo:0,0?q=");
    }
    return spanText;
}
Also used : Matcher(java.util.regex.Matcher) SpannableString(android.text.SpannableString) URLSpan(android.text.style.URLSpan) Spannable(android.text.Spannable)

Example 59 with URLSpan

use of android.text.style.URLSpan in project Android-Developers-Samples by johnjohndoe.

the class MainActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sample_main);
    // BEGIN_INCLUDE(text_auto_linkify)
    /*
         *  text_auto_linkify shows the android:autoLink property, which
         *  automatically linkifies things like URLs and phone numbers
         *  found in the text. No java code is needed to make this
         *  work.
         *  This can also be enabled programmatically by calling
         *  .setAutoLinkMask(Linkify.ALL) before the text is set on the TextView.
         *
         *  See android.text.util.Linkify for other options, for example only
         *  auto-linking email addresses or phone numbers
         */
    // END_INCLUDE(text_auto_linkify)
    // BEGIN_INCLUDE(text_html_resource)
    /*
         * text_html_resource has links specified by putting anchor tags (<a>) in the string
         * resource. By default these links will appear but not
         * respond to user input. To make them active, you need to
         * call setMovementMethod() on the TextView object.
         */
    TextView textViewResource = (TextView) findViewById(R.id.text_html_resource);
    textViewResource.setText(Html.fromHtml(getResources().getString(R.string.link_text_manual)));
    textViewResource.setMovementMethod(LinkMovementMethod.getInstance());
    // END_INCLUDE(text_html_resource)
    // BEGIN_INCLUDE(text_html_program)
    /*
         * text_html_program shows creating text with links from HTML in the Java
         * code, rather than from a string resource. Note that for a
         * fixed string, using a (localizable) resource as shown above
         * is usually a better way to go; this example is intended to
         * illustrate how you might display text that came from a
         * dynamic source (eg, the network).
         */
    TextView textViewHtml = (TextView) findViewById(R.id.text_html_program);
    textViewHtml.setText(Html.fromHtml("<b>text_html_program: Constructed from HTML programmatically.</b>" + "  Text with a <a href=\"http://www.google.com\">link</a> " + "created in the Java source code using HTML."));
    textViewHtml.setMovementMethod(LinkMovementMethod.getInstance());
    // END_INCLUDE(text_html_program)
    // BEGIN_INCLUDE(text_spannable)
    /*
         * text_spannable illustrates constructing a styled string containing a
         * link without using HTML at all. Again, for a fixed string
         * you should probably be using a string resource, not a
         * hardcoded value.
         */
    SpannableString ss = new SpannableString("text_spannable: Manually created spans. Click here to dial the phone.");
    /*
         * Make the first 38 characters bold by applying a StyleSpan with bold typeface.
         *
         * Characters 45 to 49 (the word "here") is made clickable by applying a URLSpan
         * pointing to a telephone number. Clicking it opens the "tel:" URL that starts the dialer.
         *
         * The SPAN_EXCLUSIVE_EXCLUSIVE flag defines this span as exclusive, which means
         * that it will not expand to include text inserted on either side of this span.
         */
    ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 39, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    ss.setSpan(new URLSpan("tel:4155551212"), 40 + 6, 40 + 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    TextView textViewSpan = (TextView) findViewById(R.id.text_spannable);
    textViewSpan.setText(ss);
    /*
         * Set the movement method to move between links in this TextView.
         * This means that the user traverses through links in this TextView, automatically
         * handling appropriate scrolling and key commands.
         */
    textViewSpan.setMovementMethod(LinkMovementMethod.getInstance());
// END_INCLUDE(text_spannable)
}
Also used : SpannableString(android.text.SpannableString) StyleSpan(android.text.style.StyleSpan) TextView(android.widget.TextView) URLSpan(android.text.style.URLSpan)

Example 60 with URLSpan

use of android.text.style.URLSpan in project Knife by mthli.

the class KnifeText method switchToKnifeStyle.

protected void switchToKnifeStyle(Editable editable, int start, int end) {
    BulletSpan[] bulletSpans = editable.getSpans(start, end, BulletSpan.class);
    for (BulletSpan span : bulletSpans) {
        int spanStart = editable.getSpanStart(span);
        int spanEnd = editable.getSpanEnd(span);
        spanEnd = 0 < spanEnd && spanEnd < editable.length() && editable.charAt(spanEnd) == '\n' ? spanEnd - 1 : spanEnd;
        editable.removeSpan(span);
        editable.setSpan(new KnifeBulletSpan(bulletColor, bulletRadius, bulletGapWidth), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    QuoteSpan[] quoteSpans = editable.getSpans(start, end, QuoteSpan.class);
    for (QuoteSpan span : quoteSpans) {
        int spanStart = editable.getSpanStart(span);
        int spanEnd = editable.getSpanEnd(span);
        spanEnd = 0 < spanEnd && spanEnd < editable.length() && editable.charAt(spanEnd) == '\n' ? spanEnd - 1 : spanEnd;
        editable.removeSpan(span);
        editable.setSpan(new KnifeQuoteSpan(quoteColor, quoteStripeWidth, quoteGapWidth), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    URLSpan[] urlSpans = editable.getSpans(start, end, URLSpan.class);
    for (URLSpan span : urlSpans) {
        int spanStart = editable.getSpanStart(span);
        int spanEnd = editable.getSpanEnd(span);
        editable.removeSpan(span);
        editable.setSpan(new KnifeURLSpan(span.getURL(), linkColor, linkUnderline), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
Also used : BulletSpan(android.text.style.BulletSpan) QuoteSpan(android.text.style.QuoteSpan) URLSpan(android.text.style.URLSpan)

Aggregations

URLSpan (android.text.style.URLSpan)134 SpannableString (android.text.SpannableString)36 Spannable (android.text.Spannable)22 SpannableStringBuilder (android.text.SpannableStringBuilder)21 TextPaint (android.text.TextPaint)21 Spanned (android.text.Spanned)20 TextView (android.widget.TextView)19 ForegroundColorSpan (android.text.style.ForegroundColorSpan)16 StyleSpan (android.text.style.StyleSpan)16 UnderlineSpan (android.text.style.UnderlineSpan)14 Paint (android.graphics.Paint)13 ImageSpan (android.text.style.ImageSpan)13 StrikethroughSpan (android.text.style.StrikethroughSpan)13 TypefaceSpan (android.text.style.TypefaceSpan)13 View (android.view.View)13 Intent (android.content.Intent)12 AbsoluteSizeSpan (android.text.style.AbsoluteSizeSpan)12 BackgroundColorSpan (android.text.style.BackgroundColorSpan)12 ClickableSpan (android.text.style.ClickableSpan)12 SubscriptSpan (android.text.style.SubscriptSpan)12