본문 바로가기

어플리케이션 구성/인텐트(Intent)

인텐트 필터 : NotePad Manifest 파일 분석해보기


이번 글에서는 NotePad Manifest 파일의 인텐트 필터 부분을 분석해보도록 하겠습니다.
아래는 NotePad 의 메니페스트 파일(AndroidManifest.xml)입니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.notepad"
>
    <application android:icon="@drawable/app_notes"
        android:label="@string/app_name"
    >
        <provider android:name="NotePadProvider"
            android:authorities="com.google.provider.NotePad"
        />

        <activity android:name="NotesList" android:label="@string/title_notes_list">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
        
        <activity android:name="NoteEditor"
            android:theme="@android:style/Theme.Light"
            android:label="@string/title_note"
            android:screenOrientation="sensor"
            android:configChanges="keyboardHidden|orientation"
        >
            <!-- This filter says that we can view or edit the data of
                 a single note -->
            <intent-filter android:label="@string/resolve_edit">
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="com.android.notepad.action.EDIT_NOTE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>

            <!-- This filter says that we can create a new note inside
                 of a directory of notes. -->
            <intent-filter>
                <action android:name="android.intent.action.INSERT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>

        </activity>
        
		<activity android:name="TitleEditor" android:label="@string/title_edit_title"
				android:theme="@android:style/Theme.Dialog"
                android:windowSoftInputMode="stateVisible">
            <!-- This activity implements an alternative action that can be
                 performed on notes: editing their title.  It can be used as
                 a default operation if the user invokes this action, and is
                 available as an alternative action for any note data. -->
            <intent-filter android:label="@string/resolve_title">
                <!-- This is the action we perform.  It is a custom action we
                     define for our application, not a generic VIEW or EDIT
                     action since we are not a general note viewer/editor. -->
                <action android:name="com.android.notepad.action.EDIT_TITLE" />
                <!-- DEFAULT: execute if being directly invoked. -->
                <category android:name="android.intent.category.DEFAULT" />
                <!-- ALTERNATIVE: show as an alternative action when the user is
                     working with this type of data. -->
                <category android:name="android.intent.category.ALTERNATIVE" />
                <!-- SELECTED_ALTERNATIVE: show as an alternative action the user
                     can perform when selecting this type of data. -->
                <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                <!-- This is the data type we operate on. -->
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>

여러 항목들이 있지만, 우리가 볼 항목은 <intent-filter> 태그 내의 항목들입니다.
하나하나씩 보도록 합시다.

        
        <activity android:name="NotesList" android:label="@string/title_notes_list">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>


NotesList 액티비티의 인텐트 필터는 3개입니다, 위와 같이, 인텐트 필터는 여러개가 존재할 수 있습니다. 각각의 인텐트 필터는 서로 다른 상황에서 액티비티가 호출될 수 있는 방법에 대해 정의하고 있습니다. 첫번째 필터부터 보도록 합시다.

<intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

위의 필터는 이 액티비티가 어플리케이션의 시작점이 될 수 있음을 의미하는 액션인 ACTION_MAIN(android.intent.action.MAIN)과 이 액티비티가 어플리케이션 런처(Application Launcher)에 표시되도록 해주는 카테고리인 CATEGORY_LAUNCHER(android.intent.category.LAUNCHER)로 구성됩니다. 즉, 한마디로 말하면 액티비티가 Application Launcher (설치된 어플리케이션이 표시되는 목록)에 표시되고, 액티비티가 포함된 어플리케이션의 시작점이 될 수 있음을 의미합니다. 즉, 새로운 태스크의 시작점 (루트 액티비티)가 될 수 있다는 것이죠. 

태스크에 대한 자세한 설명은 2009/09/20 - 액티비티와 태스크(Task) 를 참조하세요.

<intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>

위의 필터는 액티비티가 암시적 인텐트 (Implicit Intent)를 통해 호출될 때의 조건들입니다. ACTION_VIEW, ACTION_EDIT, ACTION_PICK 중 하나의 액션을 가지고, type으로 vnd.android.cursor.dir/vnd.google.note를 가지는 인텐트 객체를 받을 수 있음을 의미합니다. 또한, 암시적 인텐트를 받기 위해 CATEGORY_DEFAULT 를 정의하고 있는 것을 확인할 수 있습니다. 

            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>

위의 필터도 암시적 인텐트를 통해 호출될 때의 조건입니다. ACTION_GET_CONTENT를 액션으로 가지는 인텐트 객체를 받을 수 있습니다.

NoteEditor 액티비티는 NotesList와 유사하므로 생략하고, TitleEditor 액티비티의 인텐트 필터를 보도록 하겠습니다.

<activity android:name="TitleEditor" android:label="@string/title_edit_title"
				android:theme="@android:style/Theme.Dialog"
                android:windowSoftInputMode="stateVisible">
                    <intent-filter android:label="@string/resolve_title">
                         <action android:name="com.android.notepad.action.EDIT_TITLE" />
                         <category android:name="android.intent.category.DEFAULT" />
                         <category android:name="android.intent.category.ALTERNATIVE" />
                         <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
                         <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>

액션은 지금까지 보던 것들과 별 차이가 없는데, 카테고리 중 그동안 못보던 것이 있습니다. 바로 CATEGORY_ALTERNATIVE(android.intent.category.ALTERNATIVE)와 CATEGORY_SELECTED_ALTERNATIVE(android.category.SELECTED_ALTERNATIVE) 인데요, 이것들은 무엇을 의미할까요?

그리고 위의 인텐트 필터에도 label이 붙어있습니다. 뭔가 특이한 것 같은 느낌이 폴~폴 나죠?

이것은 바로 다른 어플리케이션에서 해당 액티비티를 사용할 수 있게끔 다른 어플리케이션(액티비티)의 메뉴 등에 위의 액티비티를 호출하는 메뉴가 추가될 수 있도록 해주는 속성입니다. CATEGORY_ALTERNATIVE와 CATEGORY_SELECTED_ALTERNATIVE 속성이 그 역할을 하는데 필요한 속성이죠.

만약 내가 주소록 데이터를 가지고 어떠한 작업을 수행하는 액티비티를 만든 후 위와 같이 다른 액티비티의 메뉴에 표시될 수 있게끔 하고, 주소록에서도 메뉴에 다른 액티비티를 호출하는 메뉴가 추가될 수 있게 되어있다면, 주소록 어플리케이션에서 내가 만든 액티비티를 호출하고, 주소록에서 넘겨준 데이터를 기반으로 어떠한 작업을 처리할 수 있겠죠?

CATEGORY_ALTERNATIVE와 CATEGORY_SELECTED_ALTERNATIVE를 이용하여 다른 액티비티에서도 내가 만든 액티비티를 호출할 수 있도록 하는 것에 대해서는 양이 많은 관계로 다음 글에서 다뤄보도록 하겠습니다. :)