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의 세 가지 요소 그룹으로 구성되며, 이 조합이 구성 요소가 수신할 Intent를 결정합니다. 필터는 Intent가 각 그룹의 최소 하나의 요소와 일치하는 경우 충족된 것으로 간주됩니다.
Action은 수행 중인 작업(보기, 편집, 보내기)을 설명합니다. Category는 추가 처리 컨텍스트(예: 브라우저에서 시작 기능)를 추가합니다. Data는 URI 또는 MIME 유형을 통해 처리되는 정보의 형식을 정의합니다.
사용자 프로필에 대한 링크를 여는 Activity용 Intent Filter 예시. 필터에는 정확한 라우팅을 위한 세 가지 요소 그룹이 모두 포함되어 있습니다.
<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를 등록한 경우, 시스템은 사용자에게 선택 대화상자를 표시합니다. 사용자는 일회성 사용을 위해 애플리케이션을 선택하거나 기본 핸들러를 설정할 수 있습니다. Android 10부터 선택 대화상자는 첫 번째 호출에서만 표시되며, 이후 시스템은 사용자의 선택을 기억합니다.
우선순위를 관리하기 위해 intent-filter 태그에서 android:priority 속성을 사용합니다. 값이 높을수록 충돌 해결 시 구성 요소의 우선순위가 높아집니다. 그러나 우선순위는 다른 애플리케이션의 필터에는 작동하지 않습니다 — 이 경우 기본으로 설정된 애플리케이션이 없으면 항상 선택 대화상자가 표시됩니다.
개발자는 Intent.createChooser()를 통해 프로그래밍 방식으로 선택 대화상자를 호출할 수 있으며, 대상 Intent와 제목을 전달합니다. 이는 기본 애플리케이션이 설정되어 있더라도 애플리케이션이 사용자에게 명시적으로 핸들러를 선택하도록 제안하려는 경우 유용합니다. 예를 들어, ACTION_SEND를 통해 소셜 네트워크에 이미지를 보낼 때 createChooser를 사용하면 기본 설정에 관계없이 대화상자 표시가 보장됩니다.
가장 흔한 실수 중 하나는 Intent Filter에 DEFAULT 카테고리가 없는 것입니다. 개발자가 예제에서 구성을 복사하지만 이 카테고리를 추가하는 것을 잊어버려 Activity가 암시적 Intent를 받지 못합니다. 시스템은 암시적 호출에 대한 필터를 보지 못하지만, 명시적 Intent는 계속 작동합니다.
두 번째 흔한 실수는 전체 URI 없이 data 태그에 scheme을 잘못 지정하는 것입니다. 스키마만 지정되고 호스트가 지정되지 않은 경우, 필터는 모든 소스에서 이 스키마를 가진 모든 링크를 수락하여 신뢰할 수 없는 소스의 원치 않는 호출로 이어질 수 있습니다. 최소한 scheme과 host를 항상 지정하는 것이 좋습니다.
세 번째 실수는 Activity 코드에서 intent.data의 null 검사가 없는 것입니다. Activity가 딥 링크를 통하지 않고 런처에서 표준 방식으로 시작되는 경우 Intent에는 URI가 포함되지 않습니다. 검사 없이 intent.data에 액세스하면 NullPointerException이 발생하고 애플리케이션이 중단됩니다. safe call 연산자와 함께 항상 intent?.data?.toString()을 사용하세요.
자주 묻는 질문
네, 암시적 Intent를 수신하려면 DEFAULT 카테고리가 필수입니다. 이것이 없으면 시스템은 구성 요소에 암시적 호출을 전달하지 않으며, Intent Filter는 어차피 필터를 확인하지 않는 명시적 Intent에서만 작동합니다.
제한이 없습니다. 하나의 Activity는任意の 수의 Intent Filter를 포함할 수 있습니다. 각 필터는 별도의 처리 시나리오를 설명합니다. 예를 들어 하나는 딥 링크용, 다른 하나는 파일 처리용, 세 번째는 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 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.