Android Text Links Using Linkify

The Android framework provides an easy way to automatically convert text
patterns into clickable links. By default, Android knows how to recognize web
URLs, email addresses, map addresses, and phone numbers, but it also includes
a flexible mechanism for recognizing and converting additional text patterns,
as well.



The Android Developers Blog has an article entitled Linkify your
Text!
that provides a nice overview of the system. It discusses how the
Linkify class can be used to enable the default link patterns and
then continues with a more advanced WikiWords example that demonstrates
custom links. That article is a fine introduction to the system, so the rest
of this article will primarily focus on details not covered therein.



All of the examples in this article are based on the TextView widget. The
Linkify class can also be used to add links to Spannable text, but those
use cases won���t be covered here because their usage is nearly identical to the
TextView cases.



TextView AutoLinking

The TextView widget features an android:autoLink attribute that
controls the types of text patterns that are automatically recognized and
converted to clickable links. This attribute is a convenient way to enable
one or more of the default link patterns because it can be configured directly
from a layout without involving any additional code.



However, for those cases where programmatically setting this value is useful,
the setAutoLinkMask() function exists.



There is one important caveat to using this ���auto-linking��� functionality,
however. It appears that when ���auto-linking��� is enabled, all additional
Linkify operations are ignored. It���s unclear whether this behavior is
intentional or inadvertent, so it���s possible things could change in future
released of the Android SDK. Consider disabling ���auto-linking��� before using
any of the Linkify operations discussed below.



// Disable the text view's auto-linking behavior
textView.setAutoLinkMask(0);

Default Link Patterns

Enabling support for one of Android���s default link patterns is very easy.
Simply use the addLinks(TextView text, int mask) function and
specify a mask that describes the desired link types.



import android.text.util.Linkify;

// Recognize phone numbers and web URLs
Linkify.addLinks(text, Linkify.PHONE_NUMBERS | Linkify.WEB_URLS);

// Recognize all of the default link text patterns
Linkify.addLinks(text, Linkify.ALL);

// Disable all default link detection
Linkify.addLinks(text, 0);

Custom Link Patterns

Detecting additional types of link patterns is easy, too. The
addLinks(TextView text, Pattern pattern, String scheme)
function detects links based on a regular expression pattern.



import java.util.regex.Pattern;
import android.text.util.Linkify;

// Detect US postal ZIP codes and link to a lookup service
Pattern pattern = Pattern.compile("\\d{5}([\\-]\\d{4})?");
String scheme = "http://zipinfo.com/cgi-local/zipsrch....
Linkify.addLinks(text, pattern, scheme);

The text is scanned for pattern matches. Matches are converted to links that
are generated by appending the matched text to the provided URL scheme base.



Note that the scheme doesn���t have to be an external web-like URL. It could
also be an Android Content URI that can be used in conjunction with a content
provider
to reference application resources, for example.



Match Filters

Regular expressions are a very powerful way to match text patterns, but
sometimes a bit more flexibility is needed. The MatchFilter class
provides this capability by giving user code a chance to evaluate the link
worthiness of some matched text.



import java.util.regex.Pattern;
import android.text.util.Linkify;
import android.text.util.Linkify.MatchFilter;

// A match filter that only accepts odd numbers.
MatchFilter oddFilter = new MatchFilter() {
public final boolean acceptMatch(CharSequence s, int start, int end) {
int n = Character.digit(s.charAt(end-1), 10);
return (n & 1) == 1;
}
};

// Match all digits in the pattern but restrict links to only odd
// numbers using the filter.
Pattern pattern = Pattern.compile("[0-9]+");
Linkify.addLinks(text, pattern, "http://...", oddFilter, null);

A more complex (but useful!) example would involve matching valid dates. The
regular expression could be generous enough to match strings like ���2010-02-30���
(February 30, 2010), but a match filter could provide the logic to reject
bogus calendar dates.



Transform Filters

Up until this point, the final link was always being generated based on the
exact matched text. There are many cases where that is not desirable,
however. For example, it���s common to mention a username using the @username
syntax, but the resulting link should only include the username portion of
the text. The TransformFilter class provides a solution.



import java.util.regex.Pattern;
import android.text.util.Linkify;
import android.text.util.Linkify.TransformFilter;

// A transform filter that simply returns just the text captured by the
// first regular expression group.
TransformFilter mentionFilter = new TransformFilter() {
public final String transformUrl(final Matcher match, String url) {
return match.group(1);
}
};

// Match @mentions and capture just the username portion of the text.
Pattern pattern = Pattern.compile("@([A-Za-z0-9_-]+)");
String scheme = "http://twitter.com/";
Linkify.addLinks(text, pattern, scheme, null, mentionFilter);

This approach uses the regular expression���s capture syntax to extract just the
username portion of the pattern as a uniquely addressable match group.
Alternatively, the transform filter could just return all of the matched text
after the first character (@), but the above approach is nice because it
keeps all of the pattern���s details within the regular expression.



Of course, transform filters can be combined with match filters for ultimate
flexibility. The Android SDK uses this approach to detect wide ranges of
phone number formats (many of which include various parentheses and dashes)
while always generating a simplified link containing only digits.



Further Reading

For more information about the specific implementation details of Android���s
link generation system, the best reference is actually the source code itself.
In addition to being a good resource for understanding the system, it���s also
the best way to track down potential bugs or misunderstandings about how the
system is intended to be used.




Linkify.java - The Linkify class itself, including the MatchFilter
and TransformFilter implementations for the standard link types.
Regex.java - A collection of regular expressions and utility functions
used by Linkify to work with the standard link types.
 •  0 comments  •  flag
Share on Twitter
Published on April 08, 2010 17:00
No comments have been added yet.