본문 바로가기
Development/Android

[Android] Android Intent Filter 개념과 실전 구현 방법

by 은스타 2019. 9. 10.
반응형
Android Intent Filter 개념과 실전 구현 방법

Android Intent Filter 개념과 실전 구현 방법

Android에서 Intent Filter는 다른 앱이 자신의 Activity를 시작할 수 있도록 하는 핵심 메커니즘입니다. 예를 들어, 갤러리 앱에서 "공유" 버튼을 눌렀을 때 카카오톡, 이메일, 메시지 등 다양한 앱이 나타나는 것이 바로 Intent Filter 덕분입니다. 이 글에서는 Intent Filter의 개념부터 Action, Data, Category의 상세 설명, 그리고 실전에서 바로 활용할 수 있는 구현 방법까지 초보자도 이해할 수 있도록 상세히 알아보겠습니다.
목차
1. Intent Filter의 개념과 동작 원리
2. Intent Filter의 3가지 구성 요소
3. Intent Filter 실전 구현 예제
4. Activity에서 Intent 처리하기
5. 주의사항과 베스트 프랙티스

#1. Intent Filter의 개념과 동작 원리
Intent Filter는 다른 앱이 자신의 Activity를 시작할 수 있도록 허용하는 AndroidManifest.xml 파일의 선언입니다.
1) Intent Filter가 필요한 이유
다른 앱이 자신의 Activity를 시작할 수 있도록 하기 위해서는 AndroidManifest 파일에서 <activity> 요소에 <intent-filter> 요소를 추가해야 합니다.
(1) Intent Filter의 역할
시스템이 Intent Filter를 식별하고 설치된 모든 앱에서 지원하는 Intent의 내부 카탈로그에 해당 정보를 추가
② 앱이 암시적 인텐트로 startActivity() 또는 startActivityForResult()를 호출하면 시스템은 그 인텐트에 응답할 수 있는 Activity들을 찾습니다
사용자에게 선택 가능한 앱 목록을 제공
. . . . .
2) 명시적 Intent vs 암시적 Intent
구분 명시적 Intent 암시적 Intent
대상 지정 클래스명으로 정확히 지정 Action, Data, Category로 조건 지정
Intent Filter 불필요 필수
사용 예 같은 앱 내 Activity 전환 다른 앱 호출, 공유 기능
선택 화면 표시 안 됨 조건에 맞는 앱 목록 표시

#2. Intent Filter의 3가지 구성 요소
Activity가 처리 가능한 Intent를 올바르게 정의하려면, Activity가 받아들이는 데이터와 추가하는 인텐트 필터가 구체적이어야 합니다. Activity의 Intent Filter가 Intent 객체의 다음 기준을 충족할 경우, 시스템이 주어진 Intent를 해당 Activity에 보낼 수 있습니다.
1) Action - 수행할 작업 지정
수행할 작업의 이름을 지정하는 문자열입니다. 일반적으로 플랫폼에서 정의하는 값 중 하나를 사용합니다.
(1) 주요 Action 종류
ACTION_VIEW - 데이터를 사용자에게 표시 (URL, 연락처 등)
ACTION_SEND - 데이터를 다른 앱으로 전송 (공유 기능)
ACTION_SENDTO - 수신자를 지정하여 데이터 전송 (메시지, 이메일)
④ ACTION_EDIT - 편집 가능한 데이터에 접근
⑤ ACTION_PICK - 목록에서 항목 선택
(2) Action 선언 방법
<action> 요소를 사용하여 Intent Filter에 지정합니다. 이 요소에 지정하는 값은 API 상수 대신 작업의 전체 문자열 이름이어야 합니다.
<!-- Action 선언 예제 -->
<intent-filter>
    <action android:name="android.intent.action.SEND"/>
</intent-filter>
. . . . .
2) Data - 인텐트와 관련된 데이터
인텐트와 관련된 데이터에 대한 설명입니다. <data> 요소를 사용하여 Intent Filter에 지정합니다.
(1) Data 요소에서 지정 가능한 항목
MIME 유형 - 데이터의 형식 (text/plain, image/*, video/* 등)
URI 접두사 - 특정 URL 패턴
URI 구성표 - http, https, tel, sms 등
④ 이들의 조합으로 수락된 데이터 유형을 나타냄
(2) Data 선언 예제
<!-- MIME 타입으로 텍스트와 이미지 지정 -->
<intent-filter>
    <action android:name="android.intent.action.SEND"/>
    <data android:mimeType="text/plain"/>
    <data android:mimeType="image/*"/>
</intent-filter>

<!-- URI 스킴으로 SMS 지정 -->
<intent-filter>
    <action android:name="android.intent.action.SENDTO"/>
    <data android:scheme="sms"/>
    <data android:scheme="smsto"/>
</intent-filter>
. . . . .
3) Category - Activity의 특징 지정
인텐트를 처리하는 Activity의 특징을 지정할 수 있는 추가적인 방법을 제공합니다. 일반적으로 사용자 제스처 또는 이러한 제스처가 시작된 위치와 관련되어 있습니다.
(1) 주요 Category 종류
CATEGORY_DEFAULT - 암시적 인텐트를 수신하려면 필수
② CATEGORY_BROWSABLE - 웹 브라우저에서 실행 가능
③ CATEGORY_LAUNCHER - 앱 런처에 표시
(2) CATEGORY_DEFAULT의 중요성
모든 암시적 인텐트는 기본적으로 CATEGORY_DEFAULT로 정의됩니다. startActivity() 및 startActivityForResult() 메서드는 모든 인텐트를 마치 CATEGORY_DEFAULT 범주를 선언한 것처럼 취급합니다. Intent Filter에서 이 범주를 선언하지 않으면 어떠한 암시적 인텐트도 Activity로 확인되지 않습니다.
<!-- CATEGORY_DEFAULT는 필수 -->
<intent-filter>
    <action android:name="android.intent.action.SEND"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain"/>
</intent-filter>

#3. Intent Filter 실전 구현 예제
1) 기본 예제 - 텍스트/이미지 공유 받기
다음은 데이터 유형이 텍스트 또는 이미지인 경우 ACTION_SEND 인텐트를 처리하는 인텐트 필터가 지정된 Activity입니다.
<!-- AndroidManifest.xml -->
<activity android:name=".ShareActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>
수신되는 인텐트는 각각 하나의 작업 및 하나의 데이터 유형만 지정합니다. 하지만 <intent-filter>의 <action>, <category>, <data> 요소에 대한 여러 인스턴스를 선언해도 문제가 되지 않습니다.
. . . . .
2) 고급 예제 - 여러 Intent Filter 사용
action과 data의 두 쌍이 상호 배타적으로 동작할 경우, 어떤 데이터 유형과 페어링되었을 때 어떤 작업이 허용 가능한지를 지정하는 Intent Filter를 각각 따로 생성해야 합니다.
(1) 잘못된 예제
Activity가 ACTION_SEND 및 ACTION_SENDTO 인텐트 모두에서 텍스트와 이미지 모두를 처리한다고 가정합니다. 이런 경우, 두 작업 각각에 별도의 인텐트 필터를 정의해야 합니다.
(2) 올바른 예제
<!-- AndroidManifest.xml -->
<activity android:name=".ShareActivity"
    android:exported="true">

    <!-- SMS 전송을 위한 필터 -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms"/>
        <data android:scheme="smsto"/>
    </intent-filter>

    <!-- 텍스트/이미지 공유를 위한 필터 -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>
그 이유는 ACTION_SENDTO 인텐트는 데이터 Uri를 사용해서 send 또는 sendto URI 구성표를 사용하는 수신자 주소를 지정해야 하기 때문입니다.
. . . . .
3) 실전 예제 - 웹 링크 열기
<!-- 특정 도메인의 웹 링크를 앱에서 열기 -->
<activity android:name=".WebViewActivity"
    android:exported="true">
    <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="https"
            android:host="www.example.com"/>
    </intent-filter>
</activity>

#4. Activity에서 Intent 처리하기
Activity를 시작하는 데 사용된 Intent를 읽어 Activity에서 취할 작업을 결정할 수 있습니다.
1) Intent 데이터 가져오기
Activity가 시작되면, getIntent()를 호출하여 Activity를 시작한 Intent를 검색합니다. 이 작업은 Activity의 수명 주기 동안 언제든지 가능하지만, 일반적으로 onCreate() 또는 onStart()와 같은 초기 콜백 과정에서 수행합니다.
// Kotlin - Intent 데이터 처리
class ShareActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_share)

        // Intent 가져오기
        val intent = intent
        val action = intent.action
        val type = intent.type

        // ACTION_SEND 처리
        if (Intent.ACTION_SEND == action && type != null) {
            when {
                "text/plain" == type -> handleSendText(intent)
                type.startsWith("image/") -> handleSendImage(intent)
            }
        }
    }

    private fun handleSendText(intent: Intent) {
        val sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
        if (sharedText != null) {
            // 텍스트 처리
            Toast.makeText(this, "받은 텍스트: $sharedText", Toast.LENGTH_SHORT).show()
        }
    }

    private fun handleSendImage(intent: Intent) {
        val imageUri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
        if (imageUri != null) {
            // 이미지 처리
            val imageView = findViewById<ImageView>(R.id.imageView)
            imageView.setImageURI(imageUri)
        }
    }
}

#5. 주의사항과 베스트 프랙티스
1) 필수 주의사항
(1) CATEGORY_DEFAULT는 필수
암시적 인텐트를 수신하려면 인텐트 필터 안에 CATEGORY_DEFAULT 범주를 반드시 포함해야 합니다. Intent Filter에서 이 범주를 선언하지 않으면 어떠한 암시적 인텐트도 Activity로 확인되지 않습니다.
(2) android:exported 속성
Android 12(API 레벨 31) 이상을 타겟팅하는 앱에서 Intent Filter를 포함하는 Activity는 android:exported 속성을 명시적으로 선언해야 합니다.
. . . . .
2) 베스트 프랙티스
구체적인 필터 작성 - 처리할 수 있는 데이터만 정확히 지정
여러 필터 분리 - 상호 배타적인 action은 별도 필터로 작성
테스트 필수 - 다양한 앱에서 Intent를 보내 테스트
④ null 체크 - Intent 데이터는 항상 null 체크 후 사용

마무리
Intent Filter는 Android 앱 간 통신의 핵심 메커니즘입니다. 올바르게 구현하면 다른 앱과의 연동이 원활해지고, 사용자에게 더 나은 경험을 제공할 수 있습니다.
핵심 요약
Intent Filter는 AndroidManifest.xml에 선언하여 다른 앱이 자신의 Activity를 시작할 수 있도록 합니다
3가지 구성요소 - Action(작업), Data(데이터), Category(특징)
CATEGORY_DEFAULT는 암시적 인텐트를 위해 필수
④ 상호 배타적인 action은 별도의 Intent Filter로 분리하여 작성
⑤ getIntent()로 Intent를 가져와 데이터를 처리합니다
Intent Filter를 제대로 이해하고 활용하면 갤러리의 공유 기능, 웹 링크 열기, SMS 전송 등 다양한 앱 간 연동 기능을 구현할 수 있습니다. 특히 CATEGORY_DEFAULT를 빼먹지 않도록 주의하고, 처리할 수 있는 데이터 타입을 명확하게 지정하는 것이 중요합니다.
긴 글 읽어주셔서 감사합니다.

끝.
반응형