[안드로이드/Android] 암시적 인텐트와 매니페스트(implicit intent, manifest)

Posted by 앱해피
2015. 6. 23. 02:57 안드로이드 이론

 

암시적 인텐트(Implicit Intent)와 매니페스트(Manifest)

 

시스템이 특정 액티비티를 시작할 의도를 가진 암시적 인텐트를 받았을 때, 해당 인텐트를 인텐트 필터와 3가지 요소를 중심으로 비교해서 가장 최적의 액티비티를 검색한다.

 

• 인텐트 액션 정보 - (Action Test)

 

인텐트 카테고리 - (Category Test)

 

인텐트 데이터 정보(URI 정보, 데이터 유형) - (Data Test)

 

다음 섹션에서는 암시적 인텐트를 어떻게 적절한 컴포넌트에 매칭할 수 있는지 설명한다.
(인텐트 필터가 매니페스트 파일에 어떻게 선언되어 있는지를 고려하여)

 

Action Test - 액션 정보 테스트

 

수신하고자 하는 인텐트의 액션 정보를 지정하기 위해, 인텐트 필터는 하나 이상의 <action> 요소를 선언할 수 있다.

 

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

 

이 필터를 통과하기 위해서는, Intent 안에 지정된 액션 정보는 반드시 필터안에 열거된 액션 정보 중 하나여야만 한다.

 

필터에 어떤 액션정보도 없을 경우, 모든 암시적 인텐트는 필터에 매칭되지 않기 때문에 테스트에 실패하게 된다. 하지만, 암시적 인텐트에 액션정보를 기입하지 않을 경우, 액션정보가 없는 인텐트 필터를 통과할 수 있다.

 

Category Test - 카테고리 정보 테스트

 

수신하고자 하는 인텐트의 카테고리 정보를 지정하기 위해 인텐트 필터는 하나 이상의 <category> 요소를 선언할 수 있다.

 

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

 

암시적 인텐트가 카테고리 테스트를 통과하기 위해서는, 인텐트안에 존재하는 모든 카테고리가 필터안의 카테고리와 매칭되어야만 한다. 역은 성립하지 않아도 된다.

 

인텐트 필터가 인텐트에 포함된 카테고리 보다 더 많은 카테고리 정보를 가진다고 해도, 인텐트에 포함된 카테고리 정보가 모두 필터에도 존재한다면 테스트를 통과한다.

 

그렇기 때문에, 카테고리를 하나도 포함하지 않는 인텐트는 필터에 어떤 카테고리가 선언되어 있다고 해도 항상 테스트를 통과할 수 있다.

 

[주의] 시스템은 startActivity() 또는 startActivityForResult()를 통해서 전달되는 모든 암시적 인텐트에 CATEGORY_DEFAULT라는 카테고리 정보를 추가한다. 그렇기 때문에, 컴포넌트의 인텐트 필터에서 암시적 인텐트를 수신하고자 한다면 반드시 "android.intent.category.DEFAULT"라는 카테고리를 추가해야 한다.

 

Data Test - 데이터 정보 테스트

 

수신하고자 하는 인텐트 데이터를 지정하기 위해, 인텐트 필터는 하나 이상의 <data> 요소를 선언할 수 있다.

 

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

 

각각의 <data> 요소는 URI 구조와 데이터 유형(MIME media type)을 지정해야 한다.

URI의 각각의 부분으로써, scheme, host, port 그리고 path 속성을 갖을 수 있다.

 

<scheme>://<host>:<port>/<path>

 

content://com.example.project:200/folder/subfolder/etc

 

이 URI에서, sheme는 cotent이며 host는 com.example.project이며 port는 200이며 그리고 path는 folder/subfolder/etc다.

 

이 속성들의 각각은 <data> 요소에서 선택사항이다, 하지만 선형 종속성을 갖는다.

 

• scheme가 지정되어 있지 않다면, host는 무시된다.

 

• host가 지정되어 있지 않다면, port는 무시된다.

 

• sheme와 host가 지정되어 있지 않다면, path는 무시된다.

 

인텐트 안에 있는 URI가 필터에 있는 URI 스펙과 비교될 때, 필터 안에 있는 URI의 부분에 대해서만 비교가 진행된다.

 

• 필터에서 scheme만 지정하고 있을 때, scheme와 매칭되는 모든 URI는 필터와 매칭될 수 있다.

 

• 필터에서 scheme와 authority를 지정하고 path는 지정하지 않았을 때, 동일한 scheme와 authority를 갖는 모든 URI는 필터를 통과할 수 있다.(path와 상관 없이)

 

• 필터에서 scheme, authority 그리고 path를 지정했다면, 동일한 sheme, authority 그리고 path를 갖는 URI만 필터를 통과할 수 있다.

 

data 테스트는 인텐트에 있는 URI, MIME 유형 모두를 필터에 있는 URI, MIME 유형과 비교한다.

 

a. URI와 MIME을 둘 다 포함하지 않는 인텐트는 URI와 MIME을 둘다 포함하지 않는 인텐트 필터만 통과할 수 있다.

 

b. URI만 포함하고 MIME 유형을 포함하지 않은 인텐트는 그와 일치하는 URI를 갖고 MIME 타입을 지정하지 않은 인텐트 필터만 통과할 수 있다.

 

c. MIME 유형은 포함하나 URI는 포함하지 않는 인텐트는 그와 일치하는 MIME 유형을 갖고 URI는 지정하지 않은 필터만 통과할 수 있다.

 

d. URI와 MIME 유형 둘다 포함하고 있는 인텐트의 경우에는 1) 만약에 MIME 유형이 필터에 열거된 유형과 매칭된다면, MIME 유형 테스트를 통과할 수 있다.  2) 만약에 URI가 필터에 열거된 URI와 매칭된다면, URI 테스트를 통과할 수 있다.

 

그리고 만약 인텐트에서 content: 또는 file: URI를 가지고 있고, 필터는 URI를 명시하지 않았을 경우 테스트를 통과할 수 있다.

 

달리 말하면 필터에서 MIME 유형만 열거되어 있을 때, 컴포넌트는 content: 와 file:을 지원하는 것으로 간주된다.

 

규칙 (d)는 컴포넌트가 file 또는 content provider로 부터 로컬 데이터를 얻을 수 있다는 기대를 나타낸다. 그렇기 때문에, 필터에서는 데이터 유형만 열거하면 된다. content: 그리고 file: 을 명시적으로 선언할 필요가 없다. 아래의 코드는 해당 컴포넌트가 content provider로 부터 이미지 데이터를 수신받을 수 있고, 그것을 출력할 수 있는 컴포넌트라는 것을 뜻한다.

 

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

 

대부분 이용 가능한 데이터는 content provider에 의해서 제공되기 때문에, 데이터 타입만 지정하고 URI를 지정하지 않는 것은 일반적이다.

 

또다른 일반적인 설정은 scheme와 data 유형만 갖고 있는 필터다. 예를 들어 다음에 나와 있는 <data> 요소는 자신의 액션을 처리하기 위해서 네트워크로 부터 비디오 데이터를 회수하는 컴포넌트라는 것을 뜻한다.

 

<intent-filter>
    <data android:mimeType="http" android:type="video/*" />
    ...
</intent-filter>

 

감사합니다 ^_^