Android Text Links Using Linkify
http://www.indelible.org/ink/android-linkify/
日本語訳(こんな感じ)
アンドロイドフレームワークでは、自動的にテキストパターンをクリッカブルなリンクに変換する簡単な方法を与えてくれています。
アンドロイドは、WebURL、E-MAILアドレス、地図アドレス、電話番号を認識する方法、また、追加されたテキストパターンを同様に認識し変換するフレキシブルなメカニズムも持っています。
Android Developers Blogには、Linkify your Text! というタイトルが付けられた記事があり、すばらしいシステム概要を提供しています。
Linkify classのデフォルトリンクパターンを有効にする方法、より高度な WikiWords の例では、カスタムのリンクを解説しています。
その記事は導入としてすばらしいものですので、この記事はカバーされていないものにフォーカスを絞っています。
この記事の全ての例は、TextView widgetに基づくものです。Linkify class は、Spannable textに対してもリンクを付加することができますが、使用法がほぼTextViewのケースと同じですので、ここではカバーしません。
■TextViewの自動リンク
TextView widgetは自動的に認識し、クリッカブルなリンクに変換するテキストパターンの種類をコントロールするandroid:autoLink 属性を持っています。この属性は、コードの追加を伴うことなく、レイアウトから直接設定することができますので、一つ以上のデフォルトリンクのパターンを有効にするには便利な方法です。
また、プログラムでこの値を設定するような場合に便利な setAutoLinkMask() 関数が存在しています。
ただし、この”自動リンク”機能を使用するにあたり一つの重要な注意点があります。
自動リンク”が有効になっていると、すべての追加されたLinkify操作が無視されます。
この振る舞いは、故意によるものかまたは不注意によるものかどうか不明なので、Android SDKのリリースに伴ない、将来、変更される可能性があります。
後述のLinkifyの操作のいずれかを使用する前に、”自動リンク”が無効になっているかを考慮下さい。
// Disable the text view’s auto-linking behavior
textView.setAutoLinkMask(0);
■デフォルトのリンクのパターン
Androidのデフォルトのリンクパターンのいずれかを有効化するのは非常に簡単です。
単純にaddLinks(TextView text, int mask) 機能使用し、目的のリンクタイプを記述しているマスクを指定します。
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);
■カスタムリンクのパターン
リンクパターンのデフォルト以外の種類を検出することも簡単です。
addLinks(TextView text, Pattern pattern, String scheme) 関数は、正規表現パターンに基づいてリンクを検出しています。
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.exe?zip=”;
Linkify.addLinks(text, pattern, scheme);
テキストは、パターンマッチのためにスキャンされます。
マッチしたテキストに対して提供されたURLスキームを追加することによって、リンクに変換されます。
そのスキームは、外部のWebのようなURLである必要はないことに注意してください。
例えば、アプリケーションリソースを参照する content provider との接続に使われるAndroidのContent URIである可能性もあります。
■マッチフィルター
正規表現は、テキストパターンと一致させるには非常に強力な方法ですが、もう少し柔軟性が必要な場合があります。
MatchFilter classは、ユーザーのコードにいくつかのマッチしたテキストのリンク価値を評価する機会を与えることによってこの機能を提供します。
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);
より複雑な(しかし便利!)例としては、有効な日付と一致させることもできます。
正規表現は、大まかで”2010年2月30日”(2010年2月30日)のような文字列と一致するようになるが、マッチフィルターは、偽のカレンダーの日付を拒否するロジックを提供することができます。
■変換フィルタ
ここまでは、最終的なリンクは、常に正確にマッチしたテキストに基づいて生成されていた。
ただし、多くの場合、望ましいことではありません。
例えば、@username 構文が、ユーザ名に使用している場合に一般言及されますが、結果のリンクに ユーザー名 テキストのusername部分のみを、含めたい時です。
TransformFilter classは、このソリューションを提供しています。
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);
このアプローチは、ユニークなアドレス可能なmatchグループとしてのパターン、usernameの部分を抽出するための正規表現のキャプチャ構文を使います。
変換フィルタは、最初の文字(@)の後の一致したテキスト全てのみを戻すことができるが、上記のアプローチの方が良い、なぜなら、正規表現内の全てのパターンを保持するからです。
もちろん、変換フィルタは、一致フィルタと組み合わせることができる究極の柔軟性がある。
Android SDKには、常に数字だけを含む簡易リンクを生成しながら(その多くは様々な括弧やダッシュを含む)範囲の広い電話番号の形式を検出するために、このアプローチを使用しています。
■さらに読む
Androidのリンク生成システムの特定の実装詳細について、より多くの情報を求めるにあたって、最高の参照は、実際にはソースコードそのものです。
システムを理解するための優れたリソースであることに加えて、それはまた、システムの利用を志すにあたって、間違った理解や潜在的なバグを追跡するための最良の方法です。