API GUIDE/2. App Components
2014. 3. 3. 08:33


 

 

안드로이드 앱 독학으로 개발하기 - 일반적인 인텐트(Common Intents) (2)


안드로이드 개발자 사이트에 있는 글 중에 현재까지 1/10도 번역하지 못했지만 지금까지의 글만 보면 안드로이드는 인텐트 없이 아무것도 할 수 것이 아닌가 할 정도록 인텐트를 반복적으로 설명하고 있습니다. 물론, 액티비티, 서비스 등등 다른 중요 키워드들도 많았지만 인텐트만큼은 아니었지요.


이렇게 강조하고 있다는 것은 당연히 매우 중요하다는 뜻이겠죠. 그런 인텐트를 전부 다 외운다는 건 어렵겠지만 이 글에 나오는 것들만 알고 있으면 앱 개발에 있어 큰 문제는 없을 것 같습니다.


이제 일반적인 인텐트의 종류가 얼마남지 않았습니다. 자 그럼 끝까지 다 읽어서 인텐트를 확실하게 알고 개발해 보도록 합시다.


무슨 일이든 기초가 중요합니다. 그러니 지금 이 순간 열심히 공부해서 멋진 안드로이드 앱을 개발해 보자구요. 언제나 그렇듯 오역, 오타, 깨진 링크가 있으면 제보 부탁드립니다.


 

저작권 표시 : 

 

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.

 

현재 보시는 페이지는 안드로이드 오픈 소스 프로젝트에 의해 작성되고 공유된 작업물의 수정/번역본이며 크리에이티브 커먼즈 저작자 표시 2.5 라이센스에 기술된 조건의 사용 근거를 따른 것입니다.

 

본 문서의 원본은 http://developer.android.com/guide/components/intents-common.html이며 안드로이드 4.4 Kitkat 기준으로 설명되었습니다.


일반적인 인텐트(Common Intents)



파일 저장소(File Storage)



지정한 타입의 파일 획득하기(Retrieve a specific type of file)

사용자가 문서나 사진같은 파일을 선택하고 그 파일을 앱에서 참조할 수 있도록 요청하려면 ACTION_GET_CONTENT 액션을 사용하고 원하는 MIME 타입을 지정한다. 앱으로 반환된 파일의 참조는 현재의 액티비티가 소멸 될 때 까지만 일시적으로 사용가능한 것이기 때문에 나중에 다시 읽을 수 있도록 하려면 파일의 복사본을 만들어 두어야 한다. 이 인텐트는 사용자가 새로운 파일을 만드는 것도 가능하도록 해준다. 예를 들어, 저장된 사진을 선택하도록 하는 대신에 카메라로 새로운 사진을 촬영하도록 할 수도 있다.


결과 Intent는 파일을 가리키는 URI를 포함한 채 onActivityResult() 콜백 메서드로 전달된다. URI는 http: URI, file: URI, content: URI 중 어떤 것이라도 될 수 있다. 하지만 컨텐트 프로바이더로 접근 가능하고 (content: URI) openFileDescriptor() 메서드로 파일 스트림을 만들 수 있는 파일만 선택가능ㅎ도록 제한하고 싶다면 인텐트에 CATEGORY_OPENABLE 카테고리를 추가해 준다.


안드로이드 4.3(API 레벨 18)이상에서는 인텐트에 EXTRA_ALLOW_MULTIPLE을 추가하고 true로 설정하면 여러 개의 파일을 선택하도록 할 수도 있다. 그런 후에 getClipData() 메서드로 ClipData 오브젝트를 구하면 선택된 파일들을 각각 액세스 할 수 있다.


액션(Action)

ACTION_GET_CONTENT


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

사용자가 선택할 파일의 타입에 상응하는 MIME 타입



부가정보(Extras; 선택사항)

EXTRA_ALLOW_MULTIPLE

사용자가 동시에 여러 개의 파일을 선택할 수 있는지 여부를 나타내는 boolean(true or false) 값

EXTRA_LOCAL_ONLY

외부 서비스로부터 다운로드 받는 파일이 아니라 기기내에 존재하는 파일만 선택하도록 할 지 여부를 나타내는 boolean(true or false) 값


카테고리(Category; 선택사항)

CATEGORY_OPENABLE

openFileDescriptor()로 열어서 파일 스트림을 구할 수 있는 "열 수 있는" 파일만 선택하도록 하기 위한 값.


사진 파일을 얻는 인텐트 예제 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri
        ...
    }
}


사진 파일을 반환하는 인텐트 필터 예제 :

1
2
3
4
5
6
7
8
9
10
11
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor() -->

        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

특정 타입의 파일 열기(Open a specific type of file)

안드로이드 4.4 이상에서는 앱에서 사용할 파일의 복사본을 만드는 대신에 (ACTION_GET_CONTENT 액션을 사용할 때) ACTION_OPEN_DOCUMENT 액션과 MIME 타입을 지정하여 다른 앱에서 관리중인 파일을 열도록 요청할 수 있다. 또한 ACTION_CREATE_DOCUMENT를 사용하면 여러분의 앱으로 쓰기가 가능한 새로운 문서를 만들도록 할 수도 있다. 예를 들어, 이미 저장되어 있는 PDF문서를 선택하도록 하는 대신에 ACTION_CREATE_DOCUMENT를 사용해서 새로운 문서가 만들어질 위치를 사용자가 선택하도록 할 수 있다.(그 위치는 다른 앱에서 관리하는 문서 저장공간이다.) 그러면 여러분의 앱은 새로운 문서를 작성할 수 있는 위치의 URI를 획득할 수 있다.


ACTION_GET_CONTENT 액션을 사용하면 onActivityResult()를 통해 해당 파일의 URI를 돌려준다. 반면에 ACTION_OPEN_DOCUMENT, ACTION_CREATE_DOCUMENT를 사용하면 항상 DocumentsProvider를 통해 선택된 파일에 대한 content: URI를 되돌려준다. 그러면 openFileDescriptor()를 사용해서 파일을 열 수 있고 DocumentsContract.Document의 컬럼을 사용해 상세한 내용을 쿼리해 볼 수 있다.


반환된(획득된) URI는 앱이 동작하는 동안에는 파일을 읽고 쓸 수가 있다. 그래서 ACTION_OPEN_DOCUMENT를 사용하면 파일의 복사본을 만들어 두어야 하는 ACTION_GET_CONTENT와는 달리 아무때나 파일을 열고 수정할 수 있기 때문에 상당히 유용하다.


인텐트에 EXTRA_ALLOW_MULTIPLE을 추가하고 true로 설정하면 사용자가 여러 개의 파일을 선택하도록 할 수 있다. 사용자가 하나의 아이템만 선택하면 getData() 메서드로 그 아이템을 획득할 수 있다. 사용자가 여러 개의 아이템을 선택하면 getData()는 null을 리턴하고 대신에 getClipData()로 부터 반환되는 ClipData 오브젝트를 통해 각 아이템을 획득할 수 있다.


Note : ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT를 사용하려면 MIME 타입을 반드시 설정해야 하며 CATEGORY_OPENABLE 카테고리를 반드시 선언해야 한다. 필요하다면 부가정보키 EXTRA_MIME_TYPES를 사용하여 MIME 타입의 배열을 추가하면 하나 이상의 MIME 타입을 설정할 수도 있다. 단, 이 방법을 사용할 때는 setType() 메서드를 사용하여 메인 MIME 타입에 "*/*"를 세팅해 준다.


액션(Action)

ACTION_OPEN_DOCUMENT 또는

ACTION_CREATE_DOCUMENT


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

사용자가 선택해야 하는 파일타입에 상응하는 MIME 타입


부가정보(Extras; 선택사항)

EXTRA_MIME_TYPES

앱이 요구하는 파일 타입들에 대한 MIME 타입의 배열. 부가정보에 이 키 값을 사용하면 메인 MIME 타입은 setType() 메서드를 통하여 반드시 "*/*"로 세팅해 주어야 한다.

EXTRA_ALLOW_MULTIPLE

사용자가 동시에 여러 개의 파일을 선택할 수 있는지 여부를 나타내는 boolean(true or false) 값

EXTRA_TITLE

ACTION_CREATE_DOCUMENT 액션을 사용할 때 파일 이름을 지정한다.

EXTRA_LOCAL_ONLY

외부 서비스로부터 다운로드 받는 파일이 아니라 기기내에 존재하는 파일만 선택하도록 할 지 여부를 나타내는 boolean(true or false) 값


카테고리(Category)

CATEGORY_OPENABLE

openFileDescriptor()로 열어서 파일 스트림을 구할 수 있는 "열 수 있는" 파일만 선택하도록 하기 위한 값.


사진 파일을 얻는 인텐트 예제 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}


사실 서드파티 앱은 ACTION_OPEN_DOCUMENT 액션이 담긴 인텐트를 처리할 수가 없다. 대신 시스템이 받아서 통합 UI를 통해 다양한 앱으로부터 사용가능한 모든 파일을 디스플레이 해 준다.


여러분의 앱에 있는 파일들을 이 UI에 표시되고 다른 앱에서 열어볼 수 있도록 하려면 DocumentsProvider를 구현해야 하며 인텐트 필터에 PROVIDER_INTERFACE("android.content.action.DOCUMENTS_PROVIDER")가 포함되어 있어야 한다. 다음은 그 예제다.


1
2
3
4
5
6
7
8
<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">

    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>


다른 앱에 있는 파일을 만들고 사용하는 법에 대해 더 알고 싶다면 Stroage Access Framework 가이드를 참고하기 바란다.



지도(Maps)



지도 상에 위치 표시하기(Show a location on a map)

지도를 열어보려면 ACTION_VIEW 액션을 사용하고 아래에 정의된 스키마 중의 하나로 인텐트에 위치정보를 지정해 준다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

geo:latitude,longitude

주어진 위도와 경도로 맵에 위치를 표시한다.

예 : "geo:47.6,-122.3"


geo:latitude,longitude?z=zoom

주어진 위도와 경도를 정해진 줌 레벨로 지도에 표시한다. 줌 레벨1은 지구 전체를 보여주며 주어진 위도와 경도가 화면 중앙에 위치된다. 가장 높은(확대된) 줌 레벨은 23이다.

예 : "geo:47.6,-122.3?z=11"


geo:0,0?q=lat,lng(label)

주어진 위도와 경도를 라벨과 함께 표시한다.

예 : "geo:0,0?q=34.99,-106.61(Treasure)"


geo:0,0?q=my+street+address

"my street address"의 위치를 표시한다.(특정 주소나 위치 찾기 가능한 주소)

예 : "geo:0,0?q=1600+amphitheatre+parkway+ca"


MIME Type

필요없음


인텐트 예제 :

1
2
3
4
5
6
7
public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>



음악 / 동영상(Music or Video)



음악 파일 재생하기

음악 파일을 재생하려면 ACTION_VIEW 액션을 사용하고 인텐트 데이터에 파일을 가리키는 URI 위치를 지정한다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

file:<URI>

content:<URI>

http:<URL>


MIME Type

"audio/*"

"application/ogg"

"application/x-ogg"

"application/itunes"

또는 앱이 필요로 하는 다른 타입


인텐트 예제 :

1
2
3
4
5
6
7
public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>



전화(Phone)



전화 걸기(Initiate a phone call)

전화 앱을 열고 전화번호가 입력되도록 하려면 ACTION_DIAL 액션을 사용하고 아래 정의된 URI 스키마를 사용하여 전화번호를 지정한다. 전화 앱이 실행되면 전화번호가 입력된 상태가 되지만 반드시 사용자가 "통화"버튼을 눌러야만 전화가 걸린다.


액션(Action)

ACTION_DIAL


데이터 URI 스키마(Data URI Scheme)

tel:<phone-number>


MIME Type

필요없음


유효한 전화번호는 the IETF RFC 3966에 정의되어 있다. 유효한 전화번호의 예는 다음과 같다.

  • tel:2125551212
  • tel:(212) 555 1212


전화 다이얼러는 전화번호 같은 일반적인 스키마에서 유연하게 잘 동작한다. 그래서 스킴의 내용이 규칙에 정확히 맞지 않아도 Uri.parse() 메서드를 사용하는데는 큰 문제가 없다. 하지만 사용해 본 적이 없고 잘 동작할 지 확실하지 않다면 Uri.fromParts() 메서드를 대신 사용하도록 한다.


인텐트 예제 :

1
2
3
4
5
6
7
public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}



환경 설정(Settings)



환경 설정의 특정 부분 열기(Open a specific section of Settings)

사용자가 시스템 설정의 일부분을 바꿀 수 있도록 특정 환경 설정 창을 열고 싶을 때는 다음의 액션 중 하나를 액션으로 사용한다.


액션(Action)

ACTION_SETTINGS

ACTION_WIRELESS_SETTINGS

ACTION_AIRPLANE_MODE_SETTINGS

ACTION_WIFI_SETTINGS

ACTION_APN_SETTINGS

ACTION_BLUETOOTH_SETTINGS

ACTION_DATE_SETTINGS

ACTION_LOCALE_SETTINGS

ACTION_INPUT_METHOD_SETTINGS

ACTION_DISPLAY_SETTINGS

ACTION_SECURITY_SETTINGS

ACTION_LOCATION_SOURCE_SETTINGS

ACTION_INTERNAL_STORAGE_SETTINGS

ACTION_MEMORY_CARD_SETTINGS


이 외에 또다른 설정 화면에 대한 정보는 Settings 화면을 참조하기 바란다.


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

필요없음


인텐트 예제 :

1
2
3
4
5
6
public void openWifiSettings() {
    Intent intent = new Intent(Intent.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}



문자 메세지(Text Messaging)



첨부와 함께 SMS/MMS 메시지 보내기(Compose an SMS/MMS message with attachment)

SMS 또는 MMS 문자 메시지를 보내려면 다음의 인텐트 액션을 사용하고 전화번호, 제목, 내용 등과 같은 메시지의 세부 내용은 다음 목록에 있는 부가정보키를 사용하여 지정한다.


액션(Action)

ACTION_SENDTO 또는

ACTION_SEND 또는

ACTION_SEND_MULTIPLE


데이터 URI 스키마(Data URI Scheme)

sms:<phone_number>

smsto:<phone_number>

mms:<phone_number>

mmsto:<phone_number>


이 스키마들은 모두 동일하게 취급된다.


MIME Type

PLAIN_TEXT_TYPE ("text/plain")

"image/*"

"video/*"


부가정보(Extras; 선택사항)

"subject"

메시지의 제목을 위한 문자열(보통 MMS에만 필요하다.)

"sms_body"

메시지 본문을 위한 문자열

EXTRA_STREAM

첨부하고자 하는 사진이나 동영상을 가리키는 Uri. 만일 ACTION_SEND_MULTIPLE 액션을 사용한다면 첨부하려는 사진들이나 동영상들의 Uri로 이루어진 ArrayList 값이 되어야 한다.


인텐트 예제 :

1
2
3
4
5
6
7
8
9
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


이 인텐트가 이메일 앱이나 소셜 앱이 아닌 문자메시지 앱으로 처리되도록 하고 싶다면 ACTION_SENDTO 액션을 사용하고 데이터 스키마에 "smsto:"를 포함시키도록 한다. 다음은 그 예제다.


1
2
3
4
5
6
7
8
9
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // This ensures only SMS apps respond
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>


Note : 안드로이드 4.4버전 이상에서 기본 SMS 앱으로 사용가능한 SMS/MMS 메세지 앱을 개발 중이라면 몇몇 추가적인 액션을 인텐트 필터에 추가로 구현해야 한다. 더 자세한 정보는 Telephony 문서를 참조하기 바란다.



웹 브라우저(Web Browser)



웹 URL 열기(Load a web URL)

웹 피이지를 열려면 ACTION_VIEW 액션을 사용하고 인텐트 데이터에 웹 URL을 지정한다.


액션(Action)

ACTION_VIEW


데이터 URI 스키마(Data URI Scheme)

http:<URL>

https:<URL>

이 스키마들은 모두 동일하게 취급된다.


MIME Type

PLAIN_TEXT_TYPE ("text/plain")

"text/html"

"application/xhtml+xml"

"application/vnd.wap.xhtml+xml"


인텐트 예제 :

1
2
3
4
5
6
7
public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


인텐트 필터 예제 :

1
2
3
4
5
6
7
8
9
10
11
<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->

        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>


Tip : 여러분의 앱이 웹 사이트와 비슷한 기능을 제공한다면 그 웹사이트를 가리키는 URL을 포함한 인텐트 필터를 선언해야 한다. 그러면 여러분의 앱을 설치한 사용자가 여러분의 웹 사이트를 가리키는 이메일이나 다른 웹 사이트의 링크를 누르게 되면 웹 페이지 대신에 여러분의 앱이 실행된다.


웹 검색하기(Perform a web search)

웹 검색을 하려면 ACTION_WEB_SEARCH 액션을 사용하고 SearchManager.QUERY 부가정보키에 검색할 문자열을 지정해 준다.


액션(Action)

ACTION_WEB_SEARCH


데이터 URI 스키마(Data URI Scheme)

필요없음


MIME Type

필요없음


부가정보(Extras)

SearchManager.QUERY

검색할 문자열


인텐트 예제 :

1
2
3
4
5
6
7
public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}


이번 글은 여기까지 입니다.


그럼 다음 글에서 뵙겠습니다.


다음 글 >> 

이전 글 >> 일반적인 인텐트(Common Intents) (1)


posted by 리치크루