インテント解決とインテントフィルター
アンドロイドではインテントによって、アプリケーションのコアコンポーネントを起動します。
明示的なインテントと暗黙的なインテントについては、「明示的インテントと暗黙的インテント」で説明しました。
ここでは暗黙的インテントを実現するための仕組みである、インテント解決 (Intent Resolution) とインテント・フィルター (Intent Filter) を、実際に実装することによって説明します。
インテント解決とインテントフィルター
ここでは次のようなアプリケーションを考えます。
アプリケーションは二つ。"IntentTest1" というアプリケーションと "IntentTest1View" というアプリケーションです。
ひとつめのアプリケーション "IntentTest1" では、テキストボックス (EditText) に入力した URI をデータ、かつ、アクションを ACTION_VIEW とした暗黙的インテントを作成して、 アクティビティの開始を試みます。
そこで、EditText に "http://www.google.com/" と入力して "Go" ボタンをクリックします。
すると、URI "http://www.google.com/" を表示するためのアプリケーションとして、アンドロイドの標準ブラウザと、 ここで作成した IntentTest1View の二つが表示されます。
ここで標準のブラウザ (Browser) を選択すれば、ブラウザが起動して "http://www.google.com/" にナビゲートされます。
もし "IntentTest1View" の方を選択すれば、IntentTest1View アプリケーション内のアクティビティが起動します。
ここでは単に文字を表示しているだけです。
さらに、http という言わばメジャーなスキームではなく、カスタムのスキーマも試してみましょう。 ここでは次のように "foo://com.keicode.intenttest1:1234/" というような URI を処理することを試します。
"Go" ボタンをクリックすると、"IntentTest1View" のアクティビティが起動します。
以上の流れをどのように実現するか見ていきます。
暗黙的インテントを用いたアクティビティの開始方法
暗黙的インテントは、明示的インテントと暗黙的インテント で説明したように、 次のように作成してアクティビティの開始を試みています。
String uri = urlEditText.getText().toString();
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setData(Uri.parse(uri));
startActivity(intent);
urlEditText は EditText の参照です。要は入力された文字列が変数 uri に入っています。
インテントフィルターの設定
一方、インテントメッセージを受け取る(受け取りたい)アプリケーション "IntentTest1View" 側では、アクティビティを三つ作成しています。
- MainActivity → メインとなるアクティビティ
- MyBrowserActivity → http://... の場合
- MyCustomActivity → foo://com.keicode.intenttest1:1234/ の場合
メインのアクティビティは特に何も問題ないと思いますが、追加した二つのアクティビティについては AndroidManifest.xml にて次のようにしています。
<activity android:name=".MyBrowserActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"/>
</intent-filter>
</activity>
<activity android:name=".MyCustomActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<data
android:scheme="foo"
android:host="com.keicode.intenttest1"
android:port="1234"/>
</intent-filter>
</activity>
ここでそれぞれのアクティビティの設定で、インテント・フィルター (Intent Filters) が設定されています。 インテントフィルターを用いて、システムが暗黙的インテントの処理方法を知ることができます。
MyBrowserActivity については、アクションが "android.intent.action.VIEW"、カテゴリはデフォルト、data としてスキーム (android:scheme) が "http" と指定されています。
このように指定すると、http://www.google.com/ などの URI の VIEW アクション (のデフォルトカテゴリ) 時に利用できるアクティビティである、と、システムに伝えることができるのです。
さらに、MyCustomActivity のインテントフィルターではカスタム・スキームとして "foo" を指定しています。そして、ホスト、ポートがそれぞれ、 "com.keicode.intenttest1"、"1234" です。
そもそも、スキーム、ホスト、ポート等は、次のように決められています。
scheme://host:port/
これがインテントフィルターに指定したものと合致したときに、システムがそのアクティビティを取り上げることになります。
このように、システムがインテントフィルターを用いて特定の条件 (URI、アクション、カテゴリ) を処理するアクティビティを選択する処理過程を、 インテント解決 (Intent Resolution) といいます。
尚、インテントを受け取った側のアクティビティでは、次のようにして URI を解析することが可能です。
Intent intent = getIntent();
Uri uri = intent.getData();
Log.d(TAG, "URI=" + uri.toString());
Log.d(TAG, "scheme=" + uri.getScheme());
Log.d(TAG, "host=" + uri.getHost());
Log.d(TAG, "port=" + uri.getPort());
Log.d(TAG, "path=" + uri.getPath());