Intent FilterはAndroidManifest.xml内の宣言的な記述で、アプリケーションコンポーネントが処理できる暗黙的インテントをシステムに通知します。Android Developer Guideによると、フィルターにはaction、category、dataが含まれており、これらに基づいてシステムは他のアプリケーションやシステムイベントからの呼び出しをルーティングします。Android開発では、異なるアプリケーションのコンポーネント間の疎結合の主要メカニズムとしてIntent Filterを使用します。
ポイント
Intent FilterはAndroidアプリケーションの設定要素で、特定のタイプの暗黙的インテントを処理するコンポーネントの能力をシステムに通知します。特定のクラスを指定する明示的Intentとは異なり、暗黙的Intentには必要なアクションの説明のみが含まれ、システム自体が登録されたフィルターに基づいて適切なコンポーネントを見つけます。
フィルターはAndroidManifest.xmlファイル内のコンポーネント — Activity、Service、BroadcastReceiver — の中で宣言されます。各フィルターには複数のaction、category、data要素を含めることができます。コンポーネントは無制限の数のIntent Filterを持つことができ、それぞれが異なる処理シナリオを記述します。
Intent Filterはアプリケーションコンポーネント間の疎結合の原則を実装します。アプリケーションAはアプリケーションBの存在を知る必要はありません — アクションの説明を含むIntentを送信するだけで、システムがフィルターに基づいてルーティングします。この仕組みはShare Sheet、ブラウザ選択、ディープリンク処理の基盤となっています。
明示的Intentは起動する特定のコンポーネントクラスを指定します。これらは開発者がどのActivityを開くべきか正確に把握している場合に、単一アプリケーション内の内部ナビゲーションに使用されます。暗黙的Intentにはアクションの説明のみが含まれ、コンポーネントはシステムによって動的に決定されます。
Intent Filterは暗黙的Intentでのみ機能します。Intentが特定のクラスを指定している場合、システムはすべてのフィルターを無視して指定されたコンポーネントを直接起動します。フィルターは暗黙的呼び出しを解決するときにのみチェックされるため、アプリケーション間の相互作用の重要な要素となります。
| 特性 | 明示的Intent | 暗黙的Intent |
|---|---|---|
| コンポーネント | 明示的に指定(className) | システムが決定 |
| Intent Filter | 不要 | 必須 |
| 例 | startActivity(Intent(this, ProfileActivity::class.java)) | Intent(ACTION_VIEW, Uri.parse(”https://example.com”)) |
| セキュリティ | 高い(傍受不可) | 低い(競合の可能性) |
各Intent Filterはaction、category、dataの3つの要素グループで構成され、その組み合わせによってコンポーネントが受け取るIntentが決まります。フィルターはIntentが各グループの少なくとも1つの要素と一致した場合に満たされたと見なされます。
Actionは実行される操作(表示、編集、送信)を記述します。Categoryは追加の処理コンテキスト(ブラウザからの起動機能など)を追加します。DataはURIまたはMIMEタイプを介して処理される情報の形式を定義します。
ユーザープロファイルへのリンクを開くActivityのIntent Filterの例。フィルターには正確なルーティングのために3つの要素グループすべてが含まれています。
<activity android:name=".ProfileActivity">
<intent-filter>
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="profile" />
</intent-filter>
</activity>
category DEFAULTの必須指定に注意してください — これがないとシステムはコンポーネントに暗黙的Intentを渡しません。BROWSABLEカテゴリは、リンクをブラウザから処理する必要がある場合に追加されます。
Androidでのディープリンクは、action VIEWとスキーム、ホスト、パスを含むdataタグを持つIntent Filterを介して設定されます。myapp://profile/42のようなリンクを辿ると、システムは一致するフィルターを持つActivityを見つけ、渡されたURIで起動します。正確なマッチングのためにpathPrefix、pathPattern、pathを正しく設定することが重要です。
Android 6(API 23)以降、App Linksのサポートが追加されました — HTTPS経由で検証されたディープリンクです。App Linksは同じIntent Filterを使用しますが、Digital Asset Linksによる追加のドメイン検証があります。検証後、システムは選択ダイアログなしで自動的にアプリケーションを開きます。
HTTPSリンクによる検証付きApp Linkのフィルター例。この場合、スキームは常にhttpsで、ホストはDigital Asset Linksで指定されたドメインと一致します。
<intent-filter android:autoVerify="true">
<action
android:name="android.intent.action.VIEW" />
<category
android:name="android.intent.category.DEFAULT" />
<category
android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="example.com"
android:pathPrefix="/profile" />
</intent-filter>
autoVerify属性は、アプリケーションのインストール時にDigital Asset Linksを確認するようシステムに指示します。検証が成功すると、アプリケーションは指定されたドメインとパスのデフォルトハンドラーに自動的になります。
システムがIntentを処理するコンポーネントを選択した後、開発者はターゲットコンポーネント内で受信したintentからデータを抽出する必要があります。Activityの場合はonCreate()内でgetIntent()メソッドを使用し、BroadcastReceiverの場合はIntentがパラメータとして渡されるonReceive()メソッドを使用します。
データの抽出には、操作のタイプを決定するためのaction、URIのdata、追加情報のためのextraパラメータの取得が含まれます。これらの各要素は存在しない可能性があるため、使用前にnullチェックが必須です。
KotlinでのActivityにおける受信ディープリンクの処理例。コードはIntentからURIを抽出し、ホストとパスに基づいてナビゲーション判断を行います。
class ProfileActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val uri = intent?.data
if (uri?.host == "profile") {
val userId = uri.lastPathSegment
loadProfile(userId)
}
}
}
アクティビティがディープリンクなしで起動される可能性があるため、intentとdataをnullチェックするためにsafe call演算子を使用することを推奨します。ナビゲーションで使用する前に、hostとpathSegmentもnullチェックする必要があります。
複数のアプリケーションが同じ暗黙的Intentに一致するIntent Filterを登録している場合、システムはユーザーに選択ダイアログを表示します。ユーザーは1回限りの使用のためにアプリケーションを選択するか、デフォルトハンドラーを設定できます。Android 10以降、選択ダイアログは最初の呼び出し時にのみ表示され、その後システムはユーザーの選択を記憶します。
優先順位を管理するには、intent-filterタグでandroid:priority属性を使用します。値が高いほど、競合解決時のコンポーネントの優先順位が高くなります。ただし、異なるアプリケーションのフィルターには優先順位は機能しません — この場合、デフォルトに設定されたアプリケーションがない場合は常に選択ダイアログが表示されます。
開発者はIntent.createChooser()を介してプログラムで選択ダイアログを呼び出すことができ、ターゲットIntentとタイトルを渡します。これは、デフォルトアプリケーションが設定されていても、アプリケーションがユーザーに明示的にハンドラーを選択させたい場合に便利です。例えば、ACTION_SENDを介してソーシャルネットワークに画像を送信する際にcreateChooserを使用すると、デフォルト設定に関係なくダイアログの表示が保証されます。
最もよくあるミスの1つは、Intent FilterにDEFAULTカテゴリがないことです。開発者は例から設定をコピーしますが、このカテゴリを追加するのを忘れ、その結果Activityは暗黙的Intentを受信できません。システムは暗黙的呼び出しのフィルターを認識できませんが、明示的Intentは引き続き機能します。
2つ目のよくあるミスは、完全なURIなしでdataタグにschemeを誤って指定することです。スキームのみが指定されホストが指定されていない場合、フィルターはあらゆるソースからのこのスキームを持つすべてのリンクを受け入れ、信頼できないソースからの望ましくない呼び出しにつながる可能性があります。少なくともschemeとhostを常に指定することを推奨します。
3つ目のミスは、Activityコードでintent.dataのnullチェックがないことです。Activityがディープリンク経由ではなくランチャーから標準的な方法で起動される場合、IntentはURIを含みません。チェックなしでintent.dataにアクセスするとNullPointerExceptionが発生し、アプリケーションがクラッシュします。safe call演算子を使用して常にintent?.data?.toString()を使用してください。
よくある質問
はい、暗黙的Intentを受信するにはDEFAULTカテゴリが必須です。これがないと、システムはコンポーネントに暗黙的呼び出しを渡さず、Intent Filterはフィルターをチェックしない明示的Intentでのみ機能します。
制限はありません。1つのActivityは任意の数のIntent Filterを含めることができます。各フィルターは異なる処理シナリオを記述します。例えば、1つはディープリンク用、もう1つはファイル処理用、3つ目はShare Sheet用です。
Intent Filterは暗黙的Intentを処理する一般的な仕組みです。App LinkはDigital Asset Linksによる検証を伴うIntent Filterの特殊なケースで、指定されたドメイン上のHTTPSリンクに対してアプリケーションを自動的にデフォルトハンドラーに割り当てます。
はい、Intent FilterはActivityだけでなくServiceやBroadcastReceiverにも宣言できます。Serviceの場合は他のアプリケーションからバックグラウンドサービスを実行でき、BroadcastReceiverの場合はシステムブロードキャストメッセージを受信できます。
MIMEタイプはdataタグのmimeType属性で指定します。フィルターはコンポーネントが処理できるデータタイプを決定します — 例えば、すべての画像の場合はimage/*、プレーンテキストのみの場合はtext/plain。MIMEタイプはURIスキームと組み合わせることもできます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。