[안드로이드/Android] PART4 암시적 인텐트(Implicit Intent) 매니페스트(manifest)

Posted by 앱해피
2015. 6. 22. 23:34 안드로이드 이론

 

암시적 인텐트(Implicit Intent) 수신하는 방법

 

특정 컴포넌트에서 암시적 인텐트를 받기 위해서는, 매니페스트 파일에서 <intent-filter> 요소와 함께 어플리케이션 컴포넌트 각각에 대해서 하나 이상의 인텐트 필터를 선언해야 한다. 각각의 컴포넌트는 action, data 그리고 category를 기반으로 해서 자신이 받길 원하는 인텐트의 유형을 명시해야 한다.


안드로이드 시스템은 전달되는 암시적 인텐트가 인텐트 필터 중에 하나와 매칭되는 경우 해당 컴포넌트로 암시적 인텐트를 전달해준다.

 

[주의] : 명시적 인텐트는 해당 컴포넌트에 어떤 인텐트 필터를 설정한 것과 무관하게 명시적 인텐트가 타깃으로 삼고 있는 컴포넌트에 무조건 인텐트를 전달한다.

 

어플리케이션 컴포넌트는 처리할 수 있는 작업에 따라서 별도의 필터를 선언해야만 한다. 예를 들어 이미지 갤러리와 앱의 한 액티비티가 2개의 필터를 가진다고 가정 : 1)하나는 이미지를 볼 수 있는 필터이며, 2)다른 하나는 이미지를 편집할 수 있는 필터다. 액티비티가 시작될 때, 시스템에서는 인텐트에 들어있는 정보를 시스템에 존재하는 각각의 인텐트 필터 데이터와 비교해서 실행할 컴포넌트를 결정한다.

 

각각의 인텐트 필터는 매니페스트 파일에서 <intent-filter> 요소에 의해 정의되어야 한다. <intent-filter> 내부에서 아래에 열거된 3개의 요소 중 하나 이상을 사용해서 컴포넌트에서 받아들이고자 하는 인텐트 유형을 명시할 수 있다.

 

<action>

 

name 속성으로 <intent-filter>에서 받아들이고자 하는 액션정보를 선언한다. 속성값은 액션과 관련된 스트링 상수값으로 선언되어 있어야 하며, 클래스 상수로 선언되어 있으면 안된다.

 

<data>

 

<intent-filter>에서 받아들이고자 하는 데이터의 유형을 선언한다. 데이터 URI(scheme, host, port, path 등)와 MIME 유형의 다양한 측면을 명세하는 하나 이상의 속성을 사용해야 한다.

 

<category>

 

name 속성으로 <intent-filter>에서 받아들이고자 하는 카테고리를 선언한다. 속성값은 액션과 관련된 스트링 상수값으로 선언되어 있어야 하며, 클래스 상수로 선언되어 있으면 안된다.

 

암시적 인텐트를 수신받기 위해서는, 인텐트 필터에 반드시 CATEGORY_DEFAULT  카테고리를 추가해야만 한다. startActivity()와 startActivityForResult() 메소드는 자신이 전달하는 인텐트가 기본적으로 CATEGORY_DEFAULT 카테고리가 선언된 것으로 간주하기 때문이다.

 

인텐트 필터에 CATEGORY_DEFAULT  카테고리를 추가하지 않으면 그 어떤 컴포넌트도 암시적 인텐트를 수신할 수 없다.

 

예를 들어, 아래에 ACTION_SEND 액션 정보와 text 타입의 데이터를 수신받을 수 있는 인텐트 필터가 선언된 액티비티 정보가 있다.

 

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>

        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

 

action, data 그리고 category의 여러개의 특정 조합을 처리할 수 있는 컴포넌트를 생성하기 위해서는 여러개의 인텐트 필터를 생성할 필요가 있다.

 

암시적 인텐트는 인텐트 필터에 존재하는 3가지 요소<action/data/category>를 자신이 갖는 데이터와 비교됨으로써 테스트가 진행된다. 인텐트 필터를 갖는 특정 컴포넌트에 암시적 인텐트가 전달되기 위해서 암시적 인텐트는 3가지 테스트를 모두 통과해야 한다. 3가지 요소 중 하나라도 일치하지 않을 경우 시스템에서 해당 컴포넌트로 암시적 인텐트를 전달하지 않는다. 하지만, 특정 컴포넌트는 여러개의 인텐트 필터를 가질 수 있기 때문에 암시적 인텐트는 특정 컴포넌트에 존재하는 여러 필터 중 하나를 통과할 수도 있다.

 

[주의] 어플리케이션의 서비스가 예기치 않게 동작하는 것을 피하기 위해서, 서비스를 사용할 때는 반드시 명시적 인텐트를 사용하도록 한다. 암시적 인텐트에 의해서 실행되는 것을 막기 위해 서비스와 관련된 인텐트 필터는 제거하는 것이 좋다.

 

매니페스트 파일에서 인텐트 필터를 사용하는 예제

인텐트 필터를 좀 더 잘 이해하기 위해서, 아래 나와 있는 매니페스트 파일을 살펴보자.

<activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

 

<activity android:name="ShareActivity">


    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>


    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

 

 

첫 번째 액티비티인 MainActivity는 어플리케이션의 메인 시작점이다. 즉, 유저가 어플리케이션의 아이콘을 처음 클릭했을 때 가장 먼저 실행되는 액티비티이다.

 

ACTION_MAIN이라는 액션값은 해당 컴포넌트가 앱의 메인 시작점이라는 것을 뜻한다.

 

CATEGORY_LAUNCHER라는 카테고리는 이 앱을 실행시킬 수 있는 앱 아이콘이 시스템의

앱 런처에 존재해야 한다는 것을 뜻한다.

 

위의 2가지는 액티비티가 앱 런쳐에서 보이기 위해서는 반드시 짝을 이루어야 한다.

 

두 번째 액티비티는 텍스트와 미디어 컨텐츠를 공유할 목적으로 생성된 ShareActivity라는 액티비티다. 이 액티비티와 관련된 2개의 인텐트 필터 중 하나와 매칭되는 암시적 인텐트를 생성하는 다른 어플리케이션이 있을 때, 바로 ShareActivity를 실행할 수 있다.

 

감사합니다 ^_^