👩🏻‍💻 TIL

안드로이드 인텐트 필터

ji-hyun 2022. 12. 5. 18:06

암시적 인텐트 수신

앱이 수신할 수 있는 암시적 인텐트가 어느 것인지 알리려면, <intent-filter> 요소를 사용하여 각 앱 구성 요소에 대해 하나 이상의 인텐트 필터를 메니페스트 파일에 선언합니다.

 

 

각 인텐트 필터는 인텐트의 작업, 데이터 및 카테고리를 기반으로 어느 유형의 인텐트를 수락하는지 지정합니다.

시스템은 인텐트가 인텐트 필터 중 하나를 통과한 경우에만 암시적 인텐트를 앱 구성 요소에 전달합니다.

 

 

참고: 명시적 인텐트는 항상 자신의 대상에게 전달되며, 이는 구성 요소가 어떤 인텐트 필터를 선언하든 무관합니다.

 

 

앱 구성 요소는 자신이 수행할 수 있는 각각의 고유한 작업에 대하여 별도의 필터를 선언해야 합니다.

예를 들어 이미지 갤러리 앱에 있는 어떤 액티비티에 두 개의 필터가 있을 수 있습니다.

한 필터는 이미지를 보고, 다른 필터는 이미지를 편집하기 위한 것입니다. 액티비티가 시작되면, Intent 를 검사한 다음 Intent 에 있는 정보를 근거로 어떻게 동작할 것인지 결정합니다.

 

 

각 인텐트 필터는 앱의 메니페스트 파일에 있는 <intent-filter> 요소에서 정의하고, 이는 대응되는 앱 구성 요소에서 중첩됩니다. (예: <activity> 요소)

 

<intent-filter> 내부에서는 다음과 같은 세가지 요소 중 하나 이상을 사용하여 허용할 인텐트 유형을 지정할 수 있습니다.

 

<action>

name 특성에서 허용된 인텐트 작업을 선언합니다. 이 값은 어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.

 

<data>

허용된 데이터 유형을 선언합니다. 이때 데이터 URI(scheme, host, port, path) 와 MINE 유형의 여러 가지 측면을 나타내는 하나 이상의 특성을 사용합니다.

 

<category>

name 특성에서 허용된 인텐트 카테고리를 선언합니다. 이 값은 어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.

 

 

 

참고:
암시적 인텐트를 수신하려면 CATEGORY_DEFAULT 카테고리를 인텐트 필터에 포함해야 합니다.
startActivity() 및 startActivityForResult() 메서드는 마치 CATEGORY_DEFAULT 범주를 선언한 것처럼 모든 인텐트를 취급합니다. 이 카테고리를 인텐트 필터에서 선언하지 않으면 액티비티에 어떤 암시적 인텐트도 확인되지 않습니다.

 

 

 

예를 들어 데이터 유형이 텍스트인 경우 ACTION_SEND 인텐트를 수신할 인텐트 필터가 있는 액티비티 선언은 다음과 같습니다.

 

<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> 의 인스턴스를 두 개 이상 포함하는 필터를 생성할 수 있습니다.

이렇게 하는 경우, 구성 요소가 그러한 필터 요소의 모든 조합을 처리할 수 있는지 확인해야 합니다.

 

 

여러 가지 종류의 인텐트를 처리하고자 하되 특정 조합의 작업, 데이터, 카테고리 유형으로만 한정하고자 할 때는 여러 가지 인텐트 필터를 생성해야 합니다.

 

 

암시적 인텐트는 인텐트를 세 가지 요소와 각각 비교하여 필터를 테스트합니다. 인텐트가 구성 요소에 전달되려면 세 가지 테스트를 모두 통과해야 합니다. 그 중 하나라도 통과하지 못하면 Android 시스템에서 해당 인텐트를 구성 요소에 전달하지 않습니다.

그러나 구성 요소에는 여러 개의 인텐트 필터가 있을 수 있으므로, 구성 요소의 필터 중 하나를 통과하지 않는 인텐트도 다른 필터를 통하면 성공할 수 있습니다.

 

 

 

주의:
인텐트 필터를 사용하면 다른 앱이 여러분의 구성 요소를 시작할 위험이 있습니다. 인텐트 필터는 구성 요소가 특정한 종류의 암시적 인텐트에만 응답하도록 제한하기는 하지만, 다른 개발자가 여러분의 구성 요소 이름을 알아내서 명시적 인텐트를 사용할 경우 다른 앱이 여러분의 구성 요소 이름을 알아내서 명시적 인텐트를 사용할 경우 다른 앱이 여러분의 구성 요소를 시작할 수도 있습니다. 

자신의 앱만 구성 요소를 시작하는 것이 중요할 경우 메니페스트에서 인텐트 필터를 선언하지 마세요.

* 그 대신 해당 구성 요소에 대해 exported 특성을 "false" 로 설정하세요.

마찬가지로 의도치 않게 다른 앱의 Service 를 실행하는 일을 피하려면, 항상 명시적 인텐트를 사용하여 본인의 서비스를 시작하세요.

 

 

 

 

참고:
모든 액티비티는 메니페스트 파일에서 인텐트 필터를 선언해야 합니다.

 

 

 

 

 

 

 

 

필터 예시

 

<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="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

 

첫번째 액티비티인 MainActivity 는 앱의 주요 진입 지점입니다. 즉 이것은 사용자가 시작 관리자 아이콘을 사용하여 앱을 처음 시작할 때 열리는 액티비티입니다.

 

 

- <ACTION_MAIN> 작업은 이것이 주요 진입 지점이며 어느 인텐트 데이터도 기대하지 않는다는 것을 나타냄

- <CATEGORY_LAUNCHER> 카테고리는 이 액티비티의 아이콘이 시스템의 앱 시작 관리자에 배치되어야 한다는 것을 나타냅니다. <activity> 요소가 아이콘을 icon 으로 지정하지 않은 경우, 시스템은 <application> 요소로부터 가져온 아이콘을 사용합니다.

 

 

 

이를 두 가지가 짝을 이루어야 액티비티가 앱 시작 관리자에 나타날 수 있습니다.

 

 

 

 

 

https://developer.android.com/guide/components/intents-filters?hl=ko