summaryrefslogtreecommitdiff
path: root/docs/html-intl/intl/ko
diff options
context:
space:
mode:
authorTrevor Johns <trevorjohns@google.com>2016-04-05 19:43:35 -0700
committerTrevor Johns <trevorjohns@google.com>2016-04-05 20:32:07 -0700
commita5060ee80dbb48bd7fc545d2aeeeb657b79893ea (patch)
tree842bb82e198dccade4bfb3ceafcc01f96083cd34 /docs/html-intl/intl/ko
parentebf3261aa6d80ad4ca1df0fd0509961ff7a1914e (diff)
parent9577d31b10aa654d3ba63947e7733945a358395e (diff)
Merge branch 'mnc-mr-docs' into mnc-ub-dev
Large merge to reconnect automerger for docs branch to mainline. Conflicts: docs/html-intl/intl/es/index.jd docs/html-intl/intl/es/preview/download.jd docs/html-intl/intl/es/preview/index.jd docs/html-intl/intl/ja/index.jd docs/html-intl/intl/ja/preview/download.jd docs/html-intl/intl/ja/preview/index.jd docs/html-intl/intl/ko/index.jd docs/html-intl/intl/ko/preview/download.jd docs/html-intl/intl/ko/preview/index.jd docs/html-intl/intl/pt-br/index.jd docs/html-intl/intl/pt-br/preview/download.jd docs/html-intl/intl/pt-br/preview/index.jd docs/html-intl/intl/ru/index.jd docs/html-intl/intl/ru/preview/download.jd docs/html-intl/intl/ru/preview/index.jd docs/html-intl/intl/zh-cn/index.jd docs/html-intl/intl/zh-cn/preview/download.jd docs/html-intl/intl/zh-cn/preview/index.jd docs/html-intl/intl/zh-tw/index.jd docs/html-intl/intl/zh-tw/preview/download.jd docs/html-intl/intl/zh-tw/preview/index.jd docs/html/guide/topics/manifest/compatible-screens-element.jd docs/html/guide/topics/manifest/uses-feature-element.jd docs/html/preview/download.jd docs/html/preview/features/runtime-permissions.jd docs/html/sdk/index.jd docs/html/tools/revisions/studio.jd docs/html/tools/sdk/eclipse-adt.jd docs/html/tools/support-library/features.jd telephony/java/android/telephony/TelephonyManager.java Bug: 28000173 Change-Id: Iacab0481175f1b32e0ac3bab98cde9e994100e94
Diffstat (limited to 'docs/html-intl/intl/ko')
-rw-r--r--docs/html-intl/intl/ko/design/get-started/principles.jd110
-rw-r--r--docs/html-intl/intl/ko/design/material/index.jd40
-rw-r--r--docs/html-intl/intl/ko/design/patterns/compatibility.jd70
-rw-r--r--docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd38
-rw-r--r--docs/html-intl/intl/ko/design/patterns/navigation.jd102
-rw-r--r--docs/html-intl/intl/ko/distribute/index-ko.jd (renamed from docs/html-intl/intl/ko/distribute/index.jd)0
-rw-r--r--docs/html-intl/intl/ko/guide/components/activities.jd756
-rw-r--r--docs/html-intl/intl/ko/guide/components/bound-services.jd658
-rw-r--r--docs/html-intl/intl/ko/guide/components/fragments.jd812
-rw-r--r--docs/html-intl/intl/ko/guide/components/fundamentals.jd480
-rw-r--r--docs/html-intl/intl/ko/guide/components/index.jd57
-rw-r--r--docs/html-intl/intl/ko/guide/components/intents-filters.jd899
-rw-r--r--docs/html-intl/intl/ko/guide/components/loaders.jd494
-rw-r--r--docs/html-intl/intl/ko/guide/components/processes-and-threads.jd411
-rw-r--r--docs/html-intl/intl/ko/guide/components/recents.jd256
-rw-r--r--docs/html-intl/intl/ko/guide/components/services.jd813
-rw-r--r--docs/html-intl/intl/ko/guide/components/tasks-and-back-stack.jd578
-rw-r--r--docs/html-intl/intl/ko/guide/index.jd74
-rw-r--r--docs/html-intl/intl/ko/guide/topics/manifest/manifest-intro.jd517
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/calendar-provider.jd1184
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/contacts-provider.jd2356
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/content-provider-basics.jd1196
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/content-provider-creating.jd1214
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/content-providers.jd108
-rw-r--r--docs/html-intl/intl/ko/guide/topics/providers/document-provider.jd916
-rw-r--r--docs/html-intl/intl/ko/guide/topics/resources/accessing-resources.jd337
-rw-r--r--docs/html-intl/intl/ko/guide/topics/resources/overview.jd103
-rw-r--r--docs/html-intl/intl/ko/guide/topics/resources/providing-resources.jd1094
-rw-r--r--docs/html-intl/intl/ko/guide/topics/resources/runtime-changes.jd281
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/controls.jd90
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/declaring-layout.jd492
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/dialogs.jd798
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/menus.jd1031
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/notifiers/notifications.jd979
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/overview.jd71
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/settings.jd1202
-rw-r--r--docs/html-intl/intl/ko/guide/topics/ui/ui-events.jd291
-rw-r--r--docs/html-intl/intl/ko/index.jd99
-rw-r--r--docs/html-intl/intl/ko/preview/api-overview.jd521
-rw-r--r--docs/html-intl/intl/ko/preview/backup/index.jd327
-rw-r--r--docs/html-intl/intl/ko/preview/behavior-changes.jd402
-rw-r--r--docs/html-intl/intl/ko/preview/download.jd361
-rw-r--r--docs/html-intl/intl/ko/preview/features/app-linking.jd123
-rw-r--r--docs/html-intl/intl/ko/preview/features/runtime-permissions.jd794
-rw-r--r--docs/html-intl/intl/ko/preview/index.jd70
-rw-r--r--docs/html-intl/intl/ko/preview/license.jd143
-rw-r--r--docs/html-intl/intl/ko/preview/overview.jd389
-rw-r--r--docs/html-intl/intl/ko/preview/samples.jd70
-rw-r--r--docs/html-intl/intl/ko/preview/setup-sdk.jd207
-rw-r--r--docs/html-intl/intl/ko/preview/testing/guide.jd187
-rw-r--r--docs/html-intl/intl/ko/preview/testing/performance.jd656
-rw-r--r--docs/html-intl/intl/ko/sdk/index.jd431
-rw-r--r--docs/html-intl/intl/ko/sdk/installing/adding-packages.jd226
-rw-r--r--docs/html-intl/intl/ko/training/material/animations.jd550
-rw-r--r--docs/html-intl/intl/ko/training/material/compatibility.jd168
-rw-r--r--docs/html-intl/intl/ko/training/material/drawables.jd126
-rw-r--r--docs/html-intl/intl/ko/training/material/get-started.jd171
-rw-r--r--docs/html-intl/intl/ko/training/material/index.jd61
-rw-r--r--docs/html-intl/intl/ko/training/material/lists-cards.jd266
-rw-r--r--docs/html-intl/intl/ko/training/material/shadows-clipping.jd133
-rw-r--r--docs/html-intl/intl/ko/training/material/theme.jd131
61 files changed, 23094 insertions, 4426 deletions
diff --git a/docs/html-intl/intl/ko/design/get-started/principles.jd b/docs/html-intl/intl/ko/design/get-started/principles.jd
index aba8a9beaeeb..b7ca66eefc49 100644
--- a/docs/html-intl/intl/ko/design/get-started/principles.jd
+++ b/docs/html-intl/intl/ko/design/get-started/principles.jd
@@ -1,8 +1,8 @@
page.title=Android 디자인 원칙
@jd:body
-<p>이러한 디자인 원칙은 사용자의 이익을 가장 염두에 두고 Android
-사용자 환경 팀(User Experience Team)에 의해서와 이 팀을 위해 개발되었습니다. Android 개발자 및 디자이너를
+<p>이 디자인 원칙은 사용자의 이익을 가장 염두에 두고 Android
+사용자 환경 팀(User Experience Team)에 의해 이 팀을 위해 개발되었습니다. Android 개발자 및 디자이너를
위해 Android 사용자 환경 팀은 계속해서 여러
유형의 기기를 위한 상세한 디자인 가이드라인의
기저를 이루고 있습니다.</p>
@@ -14,8 +14,8 @@ page.title=Android 디자인 원칙
<h2 id="enchant-me">황홀하게 만들기</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="delight-me">놀라운 방식으로 기쁨을 주기</h4>
<p>아름다운 표면, 신중하게 위치한 애니메이션 또는 시간적으로 잘 짜여진 소리 효과는 사람들에게 즐거운
@@ -23,7 +23,7 @@ page.title=Android 디자인 원칙
힘을 가지고 있다고 느끼게 해줍니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_delight.png">
@@ -32,15 +32,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="real-objects-more-fun">버튼 및 메뉴보다 더 흥미로운 실제 사물</h4>
<p>사람들이 직접 앱 내 사물을 터치하고 조작할 수 있게 해보세요. 이는 태스크를 수행할 때
필요한 인지 노력을 줄이는 동시에 정서적인 만족을 가져다 줍니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_real_objects.png">
@@ -49,8 +49,8 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="make-it-mine">내 것으로 만들게 하기</h4>
<p>사람들은 개인적인 취향을 더하고 싶어 하는데, 그렇게 하면 마음이 편안해지고 통제할 수 있다고 느끼게 되기 때문입니다. 합리적이고
@@ -58,7 +58,7 @@ page.title=Android 디자인 원칙
주요 태스크를 저해하지 않는 범위에서 재미있고, 선택 가능한 맞춤 기능을 제공할 것을 고려해 보십시오.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_make_it_mine.png">
@@ -67,15 +67,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="get-to-know-me">사용자에 대해 파악하기</h4>
<p>시간이 지남에 따라 사람들이 선호하는 것을 알아보세요. 똑같은 선택을 매번
하도록 요구하기 보다는 이전 선택을 쉽게 접근할 수 있는 곳에 둡니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_get_to_know_me.png">
@@ -84,14 +84,14 @@ page.title=Android 디자인 원칙
<h2 id="simplify-my-life">사용자의 생활을 단순하게 만들기</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="keep-it-brief">간결하게 만들기</h4>
<p>간단한 단어로 이루어진 짧은 문구를 사용하세요. 문장이 길면 사람들이 보지 않고 넘길 가능성이 커집니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_keep_it_brief.png">
@@ -100,15 +100,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="pictures-faster-than-words">말보다 빠른 사진</h4>
<p>생각을 전달하는 데 사진을 이용할 것을 고려해 보세요. 사람들의 시선을 끌고 말보다
더 효과적일 수 있습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_pictures.png">
@@ -117,15 +117,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="decide-for-me">사용자를 대신해서 결정해 주되 최종 결정권은 사용자에게 주기</h4>
<p>먼저 물어보기 보다는 최선의 추측을 하고 조치를 취해 보세요. 선택하고 결정해야 하는 사항이 너무 많으면 사람들이
짜증을 내게 됩니다. 만약을 대비해 '실행 취소' 기능을 제공합니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_decide_for_me.png">
@@ -134,15 +134,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="only-show-when-i-need-it">사용자가 필요로 할 때 필요한 사항만 보여주기</h4>
<p>사람들은 한 번에 너무 많은 것을 보면 버거워합니다. 태스크 및 정보를 소화 가능한
작은 크기로 나누세요. 현재 필요하지 않은 옵션은 숨기고 사람들의 작업 진행에 맞게 옵션을 표시하세요.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_information_when_need_it.png">
@@ -151,15 +151,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="always-know-where-i-am">사용자 자신이 현재 어디에 있는지 항상 알도록 하기</h4>
<p>사람들에게 현재 자신이 어디에 있는지에 대한 확신을 주어야 합니다. 앱에서 장소가 명확하게 표시되게 하고,
전환을 사용하여 화면 간 관계를 보여줍니다. 현재 작업 중인 태스크에 대한 피드백을 제공합니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_navigation.png">
@@ -168,8 +168,8 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="never-lose-my-stuff">사용자가 가지고 있는 것들을 절대 잃어버리지 않도록 하기</h4>
<p>사람들이 공들여 만든 것을 저장하고 어디서든지 액세스할 수 있게 합니다. 휴대폰, 태블릿 및 컴퓨터에 걸쳐 설정,
@@ -177,7 +177,7 @@ page.title=Android 디자인 원칙
가장 쉬워집니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_never_lose_stuff.png">
@@ -186,15 +186,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="looks-same-should-act-same">똑같이 보이면 똑같이 동작되도록 하기</h4>
<p>기능을 시각적으로 단순하게 만들기 보다는 눈에 띄게 만들어 사람들이 기능적 차이를 알아볼 수 있게 합니다.
비슷하게 보이는 장소지만 같은 입력에 대해 다르게 실행되는 모드는 피하도록 합니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_looks_same.png">
@@ -203,15 +203,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="interrupt-only-if-important">중요할 때만 작업을 중단하기</h4>
<p>유능한 개인 비서와 같이 중요하지 않은 일로 사람들의 작업을 중단하지 않도록 합니다. 사람들은
작업에 계속 집중하기를 바라며, 중요하고 시간을 다투는 일을 제외하고는 작업이 중단되면 부담스럽고 짜증이 날 수 있습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_important_interruption.png">
@@ -220,8 +220,8 @@ page.title=Android 디자인 원칙
<h2 id="make-me-amazing">사용자를 놀래킬 수 있는 환경 만들기</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="give-me-tricks">어디서든 적용될 수 있는 팁 제공하기</h4>
<p>사람들은 스스로 알아내는 것을 좋아합니다. 다른 Android 앱의 시각적 패턴과 머슬 메모리(muscle memory)를 활용하여
@@ -229,7 +229,7 @@ page.title=Android 디자인 원칙
좋은 탐색 지름길이 될 수 있습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_tricks.png">
@@ -238,16 +238,16 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="its-not-my-fault">사용자가 자기 탓으로 느끼지 않게 하기</h4>
<p>사람들의 실수를 바로잡아 줄 때는 부드럽게 합니다. 사람들은
-앱을 사용할 때 스마트하게 느끼고 싶어 합니다. 뭔가 잘못될 경우, 명확한 복구 지침을 제공하되, 기술적인 세부 사항은 제공하지 않습니다.
-사람들 모르게 복구할 수 있으면 더 좋습니다.</p>
+앱을 사용할 때 자신이 스마트하다고 느끼고 싶어 합니다. 뭔가 잘못될 경우, 명확한 복구 지침을 제공하되, 기술적인 세부 사항은 그들에게 맡기세요.
+눈치채지 않게 복구할 수 있으면 더 좋습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_error.png">
@@ -256,15 +256,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="sprinkle-encouragement">격려하기</h4>
<p>복잡한 태스크를 쉽게 완료할 수 있도록 여러 단계로 나눕니다. 미묘한 반짝임일지라도
작업에 대해서 피드백을 줍니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_sprinkle_encouragement.png">
@@ -273,8 +273,8 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="do-heavy-lifting-for-me">힘든 건 대신해주기</h4>
<p>초보자들이 할 수 있을 것이라 생각하지 못한 일들을 해서 전문가처럼 느낄 수 있게 합니다. 예를
@@ -282,7 +282,7 @@ page.title=Android 디자인 원칙
겨우 몇 단계를 거치는 것만으로 멋진 사진으로 보이게 할 수 있습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_heavy_lifting.png">
@@ -291,15 +291,15 @@ page.title=Android 디자인 원칙
<div class="vspace size-2">&nbsp;</div>
-<div class="layout-content-row">
- <div class="layout-content-col span-7">
+<div class="cols">
+ <div class="col-7">
<h4 id="make-important-things-fast">중요한 일은 빨리 해결되도록 하기</h4>
<p>모든 작업이 같지는 않습니다. 앱에서 가장 중요한 것이 무엇인지 결정한 후 쉽게 찾을 수 있고
빨리 사용할 수 있도록 합니다. 일례로 카메라의 셔터 버튼이나 음악 플레이어의 일시정지 버튼이 이에 해당됩니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/principles_make_important_fast.png">
diff --git a/docs/html-intl/intl/ko/design/material/index.jd b/docs/html-intl/intl/ko/design/material/index.jd
index 31992fab666f..b24c66866b7d 100644
--- a/docs/html-intl/intl/ko/design/material/index.jd
+++ b/docs/html-intl/intl/ko/design/material/index.jd
@@ -1,7 +1,7 @@
-page.title=머티어리얼 디자인
+page.title=Android용 머티리얼 디자인
page.tags=Material,design
page.type=design
-page.image=design/material/images/MaterialLight.png
+page.image=images/cards/design-material-for-android_2x.jpg
@jd:body
@@ -9,7 +9,7 @@ page.image=design/material/images/MaterialLight.png
<a class="notice-developers right" href="{@docRoot}training/material/index.html">
<div>
<h3>개발자 문서</h3>
- <p>머티어리얼 디자인으로 앱 생성</p>
+ <p>머티리얼 디자인으로 앱 생성</p>
</div>
</a>
@@ -17,7 +17,7 @@ page.image=design/material/images/MaterialLight.png
<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw">
<div>
<h3>비디오</h3>
- <p>머티어리얼 디자인 소개</p>
+ <p>머티리얼 디자인 소개</p>
</div>
</a>
@@ -25,7 +25,7 @@ page.image=design/material/images/MaterialLight.png
<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw">
<div>
<h3>비디오</h3>
- <p>종이와 잉크: 중요한 머티어리얼</p>
+ <p>종이와 잉크: 중요한 머티리얼</p>
</div>
</a>
@@ -33,19 +33,19 @@ page.image=design/material/images/MaterialLight.png
<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc">
<div>
<h3>비디오</h3>
- <p>Google I/O 앱 내 머티어리얼 디자인</p>
+ <p>Google I/O 앱 내 머티리얼 디자인</p>
</div>
</a>
-<p itemprop="description">머티어리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및
+<p itemprop="description">머티리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및
상호 작용 디자인에 대한 종합적인 지침입니다. Android에는 이제
-머티어리얼 디자인 앱에 대한 지원이 포함되었습니다. Android 앱에서 머티어리얼 디자인을 사용하려면 <a href="http://www.google.com/design/spec">머티어리얼 디자인 사양</a>에
+머티리얼 디자인 앱에 대한 지원이 포함되었습니다. Android 앱에서 머티리얼 디자인을 사용하려면 <a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a>에
규정되어 있는 지침을 따르세요. 또한 Android 5.0(API 레벨 21) 이상에서 제공하는
새 구성 요소 및 기능을 사용하세요.</p>
-<p>Android는 머티어리얼 디자인 앱을 구축하는 데 사용할 수 있는 다음 요소를 제공합니다.</p>
+<p>Android는 머티리얼 디자인 앱을 구축하는 데 사용할 수 있는 다음 요소를 제공합니다.</p>
<ul>
<li>새로운 테마</li>
@@ -53,13 +53,13 @@ page.image=design/material/images/MaterialLight.png
<li>사용자 지정 그림자 및 애니메이션을 위한 새로운 API</li>
</ul>
-<p>Android에서 머티어리얼 디자인을 구현하는 방법에 대한 자세한 내용은
-<a href="{@docRoot}training/material/index.html">머티어리얼 디자인으로 앱 생성</a>을 참조하세요.</p>
+<p>Android에서 머티리얼 디자인을 구현하는 방법에 대한 자세한 내용은
+<a href="{@docRoot}training/material/index.html">머티리얼 디자인으로 앱 생성</a>을 참조하세요.</p>
-<h3>머티어리얼 테마</h3>
+<h3>머티리얼 테마</h3>
-<p>머티어리얼 테마는 앱에 사용할 수 있는 새로운 스타일, 색상표를
+<p>머티리얼 테마는 앱에 사용할 수 있는 새로운 스타일, 색상표를
설정할 수 있는 시스템 위젯, 그리고 터치 피드백 및 액티비티 전환을 위한 기본 애니메이션을 제공합니다.</p>
<!-- two columns -->
@@ -67,25 +67,25 @@ page.image=design/material/images/MaterialLight.png
<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
<img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" />
<div style="width:140px;margin:0 auto">
- <p style="margin-top:8px">어두운 머티어리얼 테마</p>
+ <p style="margin-top:8px">어두운 머티리얼 테마</p>
</div>
</div>
<div style="float:left;width:250px;margin-right:0px;">
<img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" />
<div style="width:140px;margin:0 auto">
- <p style="margin-top:8px">밝은 머티어리얼 테마</p>
+ <p style="margin-top:8px">밝은 머티리얼 테마</p>
</div>
</div>
<br style="clear:left"/>
</div>
-<p>자세한 내용은 <a href="{@docRoot}training/material/theme.html">머티어리얼
+<p>자세한 내용은 <a href="{@docRoot}training/material/theme.html">머티리얼
테마 사용</a>을 참조하세요.</p>
<h3>목록 및 카드</h3>
-<p>Android는 머티어리얼 디자인 스타일
+<p>Android는 머티리얼 디자인 스타일
및 애니메이션으로 카드 및 목록을 표시하는 데 사용할 수 있는 두 개의 새로운 위젯을 제공합니다.</p>
<!-- two columns -->
@@ -126,7 +126,7 @@ page.image=design/material/images/MaterialLight.png
</video>
</div>
<div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
- <em>영화를 재생하려면 기기 화면을 클릭합니다.</em>
+ <em>영화를 재생하려면 기기 화면을 클릭하세요.</em>
</div>
</div>
@@ -171,7 +171,7 @@ page.image=design/material/images/MaterialLight.png
<h3>드로어블</h3>
-<p>드로어블에 대한 다음과 같은 새 기능을 통해 머티어리얼 디자인 앱을 쉽게 구현할 수 있습니다.</p>
+<p>드로어블에 대한 다음과 같은 새 기능을 통해 머티리얼 디자인 앱을 쉽게 구현할 수 있습니다.</p>
<ul>
<li><strong>벡터 드로어블</strong>은 단색 인앱 아이콘에
@@ -182,5 +182,5 @@ page.image=design/material/images/MaterialLight.png
비트맵 이미지에서 주요 색상을 자동으로 추출할 수 있게 해줍니다.</li>
</ul>
-<p>자세한 내용은 <a href="{@docRoot}training/material/drawables.html">Drawable
+<p>자세한 내용은 <a href="{@docRoot}training/material/drawables.html">드로어블
사용</a>을 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/design/patterns/compatibility.jd b/docs/html-intl/intl/ko/design/patterns/compatibility.jd
new file mode 100644
index 000000000000..a87a8f2871ab
--- /dev/null
+++ b/docs/html-intl/intl/ko/design/patterns/compatibility.jd
@@ -0,0 +1,70 @@
+page.title=이전 버전과의 호환성
+page.tags="support"
+page.metaDescription=Android 4.x에서 어떤 방식으로 이전 버전의 하드웨어 및 OS용으로 디자인된 UI를 적용하는지에 대한 설명입니다.
+@jd:body
+
+<a class="notice-developers" href="{@docRoot}training/basics/supporting-devices/index.html">
+ <div>
+ <h3>개발자 문서</h3>
+ <p>다양한 기기 지원</p>
+ </div>
+</a>
+
+<p>Android 3.0에서 중요한 변경 사항은 다음과 같습니다.</p>
+<ul>
+<li>가상 컨트롤(Back, Home, Recents)을 통한 탐색 처리
+에 편리하도록 탐색 하드웨어 키(Back, Menu, Search, Home) 사용 중단.</li>
+<li>작업 모음에서 메뉴 사용을 위한 견고한 패턴.</li>
+</ul>
+<p>Android 4.0은 태블릿의 이러한 변경 사항들을 휴대폰 플랫폼에 적용합니다.</p>
+
+<h2 id="older-hardware">이전 하드웨어 및 앱에 Android 4.0 적용</h2>
+
+<div class="cols">
+ <div class="col-6">
+
+<h4>가상 탐색 컨트롤이 있는 휴대폰</h4>
+<p>Android 3.0 이상의 버전용으로 작성된 Android 앱은 작업 모음에 작업을 표시합니다. 작업 모음에 적합하지 않거나 최상위에 표시될 만큼 중요하지 않은 작업은 작업 오버플로우에 나타납니다.
+
+</p>
+<p>사용자는 작업 모음에서 작업 오버플로를 터치하는 방식으로 액세스합니다.</p>
+
+ </div>
+ <div class="col-7">
+
+ <img src="{@docRoot}design/media/compatibility_virtual_nav.png">
+
+ </div>
+</div>
+
+<div class="cols">
+ <div class="col-6">
+
+<h4>실제 탐색 키가 있는 휴대폰</h4>
+<p>탐색 하드웨어 키가 있는 기존 Android 휴대폰은 화면 하단에 가상 탐색 모음을 표시하지 않습니다.
+ 대신 메뉴 하드웨어 키에서 작업 오버플로를 이용할 수 있습니다. 나타나는 작업 팝업은 이전의 예와 스타일은 같지만 화면 하단에 표시됩니다.
+</p>
+
+ </div>
+ <div class="col-7">
+
+ <img src="{@docRoot}design/media/compatibility_physical_buttons.png">
+
+ </div>
+</div>
+
+<div class="cols">
+ <div class="col-6">
+
+<h4>가상 탐색 컨트롤이 있는 휴대폰의 레거시 앱</h4>
+<p>Android 2.3 이하 버전용으로 작성된 앱을 가상 탐색 컨트롤이 있는 휴대폰에서 실행하면 가상 탐색 모음의 오른쪽에 작업 오버플로가 나타납니다.
+ 이 컨트롤을 터치하여 기존 Android 메뉴 스타일로 앱의 작업을 표시할 수 있습니다.
+</p>
+
+ </div>
+ <div class="col-7">
+
+ <img src="{@docRoot}design/media/compatibility_legacy_apps.png">
+
+ </div>
+</div>
diff --git a/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd b/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd
index 2444b0e9dc7c..304a65505ac5 100644
--- a/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd
+++ b/docs/html-intl/intl/ko/design/patterns/confirming-acknowledging.jd
@@ -1,51 +1,51 @@
-page.title=확인 및 승인하기
+page.title=확인 및 승인
page.tags=dialog,toast,notification
@jd:body
<p>사용자가 앱에서 작업을 호출할 때와 같은 몇몇 상황에서는 텍스트를 통해 해당 작업을 <em>확인</em>하거나 <em>승인</em>하는 것이 좋습니다.</p>
-<div class="layout-content-row">
- <div class="layout-content-col span-6">
+<div class="cols">
+ <div class="col-6">
<img src="{@docRoot}design/media/confirm_ack_confirming.png">
- <p><strong>확인하기</strong>란, 사용자에게 방금 호출한 작업을 정말로 진행할 것인지 묻는 것입니다. 경우에 따라 확인은 고려해야 할 작업과 관련된 경고 또는 중요한 정보와 함께 표시됩니다.</p>
+ <p><strong>확인</strong>이란, 사용자에게 방금 호출한 작업을 정말로 진행할 것인지 묻는 것입니다. 경우에 따라 확인은 고려해야 할 작업과 관련된 경고 또는 중요한 정보와 함께 표시됩니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<img src="{@docRoot}design/media/confirm_ack_acknowledge.png">
- <p><strong>승인하기</strong>란, 사용자에게 방금 호출한 작업이 완료되었음을 알리는 텍스트를 표시하는 것입니다. 이는 시스템이 수행하는 암시적인 작업에 대한 불확실성을 제거해 줍니다. 경우에 따라 승인은 작업의 실행을 취소하는 옵션과 함께 표시됩니다.</p>
+ <p><strong>승인</strong>이란, 사용자에게 방금 호출한 작업이 완료되었음을 알리는 텍스트를 표시하는 것입니다. 이는 시스템이 수행하는 암시적인 작업에 대한 불확실성을 제거해 줍니다. 경우에 따라 승인은 작업의 실행을 취소하는 옵션과 함께 표시됩니다.</p>
</div>
</div>
-<p>이런 방식의 사용자와의 소통은 이미 일어난 일이나 일어날 일에 대한 불확실성을 완화시키는 데 도움이 될 수 있습니다. 또한, 확인하기 또는 승인하기는 사용자가 후회할지도 모르는 실수를 미연에 방지합니다.</p>
+<p>이런 방식의 사용자와의 소통은 이미 일어난 일이나 일어날 일에 대한 불확실성을 완화시키는 데 도움이 될 수 있습니다. 또한, 확인 또는 승인은 사용자가 후회할지도 모르는 실수를 미연에 방지합니다.</p>
-<h2>사용자 작업을 확인 또는 승인하기 적절한 경우</h2>
+<h2>사용자 작업 확인 또는 승인이 적절한 경우</h2>
<p>모든 작업에 확인 또는 승인이 적합한 것은 아닙니다. 다음 순서도를 참고하여 디자인을 결정하는 데 도움을 받으세요.</p>
<img src="{@docRoot}design/media/confirm_ack_flowchart.png">
-<h2>확인하기</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-6">
+<h2>확인</h2>
+<div class="cols">
+ <div class="col-6">
<h4>예: Google Play 도서</h4>
<img src="{@docRoot}design/media/confirm_ack_ex_books.png">
<p>이 예에서는 사용자가 Google Play 라이브러리에서 도서 삭제를 요청했습니다. 이 작업을 확인하기 위해 <a href="{@docRoot}design/building-blocks/dialogs.html#alerts">경고</a>가 나타납니다. 왜냐하면 해당 도서를 더 이상 어떠한 기기에서도 이용할 수 없다는 것을 알려야 하기 때문입니다.</p>
<p>확인 대화 상자를 작성할 때, 요청된 작업을 반향하여 제목을 의미 있게 만듭니다.</p>
</div>
- <div class="layout-content-col span-7">
+ <div class="col-7">
<h4>예: Android Beam</h4>
<img src="{@docRoot}design/media/confirm_ack_ex_beam.png">
<p>확인을 두 개의 버튼을 포함한 경고로 표시할 필요는 없습니다. Android Beam을 시작하면 사용자에게 공유할 콘텐츠를 터치하라는 메시지가 표시됩니다(이 예의 경우 사진). 진행하지 않기로 결정한 경우에는 휴대폰에서 벗어나면 됩니다.</p>
</div>
</div>
-<h2>승인하기</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-6">
+<h2>승인</h2>
+<div class="cols">
+ <div class="col-6">
<h4>예: 방치된 Gmail 초안 저장</h4>
<img src="{@docRoot}design/media/confirm_ack_ex_draftsave.png">
<p>이 예에서는 사용자가 Gmail의 메일 작성 화면에서 뒤로 또는 위로 탐색을 수행하면 예상치 못한 일이 일어나는데, 그건 바로 현재 초안이 자동으로 저장되는 것입니다. 승인은 알림 메시지 형식으로 나타납니다. 그리고 몇 초 후 사라집니다.</p>
<p>이때, 저장이 사용자가 아닌 앱에 의해 이뤄졌기 때문에 실행 취소는 적합하지 않습니다. 그리고 초안 목록으로 이동하면 쉽고 빠르게 메일 작성을 재개할 수 있습니다.</p>
</div>
- <div class="layout-content-col span-6">
+ <div class="col-6">
<h4>예: Gmail 대화 삭제</h4>
<img src="{@docRoot}design/media/confirm_ack_draft_deleted.png">
<p>사용자가 Gmail 목록에서 대화를 삭제하면, 승인이 실행 취소 옵션과 함께 표시됩니다. 승인은 사용자가 목록을 스크롤하는 등의 관련 없는 작업을 수행하기 전까지 그대로 남아 있습니다.</p>
@@ -53,14 +53,14 @@ page.tags=dialog,toast,notification
</div>
<h2>확인 또는 승인이 필요 없는 경우</h2>
-<div class="layout-content-row">
- <div class="layout-content-col span-6">
+<div class="cols">
+ <div class="col-6">
<h4>예: +1 누르기</h4>
<img style="padding: 33px 0 30px;" src="{@docRoot}design/media/confirm_ack_ex_plus1.png">
<p><strong>확인이 필요 없습니다</strong>. 사용자가 실수로 +1을 누른 경우, 별문제가 되지 않습니다. 버튼을 다시 터치하여 해당 작업의 실행을 취소하면 됩니다.</p>
<p><strong>승인이 필요 없습니다</strong>. 사용자는 +1 버튼이 바운스되고 빨간색으로 바뀌는 것을 볼 수 있습니다. 이는 매우 분명한 신호입니다.</p>
</div>
- <div class="layout-content-col span-7">
+ <div class="col-7">
<h4>예: 홈 화면에서 앱 제거하기</h4>
<img src="{@docRoot}design/media/confirm_ack_ex_removeapp.png">
<p><strong>확인이 필요 없습니다</strong>. 이는 의도적인 작업으로, 사용자는 상대적으로 크고 고립된 대상으로 항목을 끌어다 놓을 것입니다. 따라서 실수가 발생할 가능성이 매우 낮습니다. 하지만 사용자가 이 결정을 후회하는 경우, 다시 복구하는 데는 몇 초면 됩니다.</p>
diff --git a/docs/html-intl/intl/ko/design/patterns/navigation.jd b/docs/html-intl/intl/ko/design/patterns/navigation.jd
index 8e5c30bc3cc5..5f335d55408f 100644
--- a/docs/html-intl/intl/ko/design/patterns/navigation.jd
+++ b/docs/html-intl/intl/ko/design/patterns/navigation.jd
@@ -1,4 +1,4 @@
-page.title=뒤로 및 위로 탐색 기능이 포함된 탐색
+page.title=Back 탐색과 Up 탐색
page.tags="navigation","activity","task","up navigation","back navigation"
page.image=/design/media/navigation_between_siblings_gmail.png
@jd:body
@@ -6,41 +6,41 @@ page.image=/design/media/navigation_between_siblings_gmail.png
<a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
<div>
<h3>개발자 문서</h3>
- <p>효과적인 탐색 구현하기</p>
+ <p>효과적인 탐색 구현</p>
</div>
</a>
<p itemprop="description">일관적인 탐색 기능은 전반적인 사용자 환경에 필수적인 요소입니다. 일관성 없고 예상대로 진행되지 않는 기본 탐색은
사용자에게 많은 실망을 줍니다. Android 3.0에서는
-글로벌 탐색 동작에 중요한 변경 사항을 도입했습니다. 뒤로 및 위로 탐색에 대한
+글로벌 탐색 동작에 중요한 변경 사항을 도입했습니다. Back 및 Up 탐색에 대한
가이드라인을 꼼꼼히 따르면 사용자가 예상 가능하고 신뢰할 수 있는 탐색 기능이 탑재된 앱을 만들 수 있습니다.</p>
-<p>Android 2.3 이하 버전에서는
-앱 내 탐색 기능을 지원하기 위해 시스템의 <em>뒤로</em> 버튼에 의존했습니다. Android 3.0에서는 작업 모음을 도입함으로써 앱 아이콘 및 왼쪽 방향 캐럿으로 이루어진 2차 탐색 메커니즘인
-<em>위로</em> 버튼이 추가되었습니다.</p>
+<p>Android 2.3 이하 버전에서는 앱 내 탐색 기능을 지원하기 위해 시스템의 <em>Back</em> 버튼에
+의존했습니다. Android 3.0에서는 작업 모음을 도입함으로써 앱 아이콘 및 왼쪽 방향 캐럿으로 이루어진
+2차 탐색 메커니즘인<em>Up</em> 버튼이 추가되었습니다.</p>
<img src="{@docRoot}design/media/navigation_with_back_and_up.png">
-<h2 id="up-vs-back">위로 및 뒤로 비교</h2>
+<h2 id="up-vs-back">Up과 Back</h2>
-<p>위로 버튼은 화면
+<p>Up 버튼은 화면
간의 계층적 관계를 기반으로 앱 내에서 탐색할 때 사용됩니다. 예를 들어, 화면 A에 표시된 항목 목록에서 항목을 선택하면 항목에 대한 세부 정보를 표시하는 화면 B로 이동하게 되는데, 이때
화면 B는 화면 A로
-돌아가는 위로 버튼을 제공해야 합니다.</p>
-<p>화면이 앱의 최상단에 있는 경우(즉, 앱의 홈인 경우), 위로
+돌아가는 Up 버튼을 제공해야 합니다.</p>
+<p>화면이 앱의 최상단에 있는 경우(즉, 앱의 홈인 경우), Up
버튼이 표시되지 않아야 합니다.</p>
-<p>시스템의 뒤로 버튼은 사용자가 최근에 작업한 화면
+<p>시스템의 Back 버튼은 사용자가 최근에 작업한 화면
기록을 역순으로 탐색할 때 사용됩니다. 일반적으로 이 버튼은 앱의 계층 구조가 아닌 화면
간의 일시적인 관계를 기반으로 합니다.</p>
<p>또한, 앞서 본 화면이 현재 화면의 계층적 상위 화면일 경우
-뒤로 버튼을 누르는 것과 위로 버튼을 누르는 것의 결과가 동일하며, 이는 흔하게
-발생하는 동작입니다. 하지만 사용자가 앱 내에 머무는 위로 버튼과 달리, 뒤로
+Back 버튼을 누르는 것과 Up 버튼을 누르는 것의 결과가 동일하며, 이는 흔하게
+발생하는 동작입니다. 하지만 사용자가 앱 내에 머무는 Up 버튼과 달리, Back
버튼을 누르면 홈 화면 또는 다른 앱으로 돌아갈 수 있습니다.</p>
<img src="{@docRoot}design/media/navigation_up_vs_back_gmail.png">
-<p>뒤로 버튼은 화면 간 탐색과 직접적으로 관련 없는 몇 가지 동작도 지원합니다.
+<p>Back 버튼은 화면 간 탐색과 직접적으로 관련 없는 몇 가지 동작도 지원합니다.
</p>
<ul>
<li>부동 창 해제(대화 상자, 팝업)</li>
@@ -49,13 +49,13 @@ page.image=/design/media/navigation_between_siblings_gmail.png
</ul>
<h2 id="within-app">앱 내 탐색</h2>
-<h4>진입 지점이 여러 개인 화면으로 이동하기</h4>
+<h4>여러 진입 지점을 통한 화면 탐색</h4>
<p>일부 화면은 앱의 계층 구조 내에서 엄격한 위치를 가지고 있지 않는 경우가 있으며, 이 경우 여러 진입 지점을
통해서 접근할 수 있습니다. 예를 들어 설정 화면은 앱
-내의 다른 어떤 화면에서도 접근이 가능합니다. 이러한 경우, 위로 버튼을 누르면 뒤로 버튼과
-동일하게 참조하는 화면으로 돌아가게 됩니다.</p>
-<h4>화면 내에서 뷰 변경하기</h4>
-<p>화면의 뷰 옵션 변경은 위로 또는 뒤로 버튼의 동작을 변경하지 않습니다. 이는 화면이 앱 계층 구조 내에서 여전히 동일한 위치에
+내의 다른 어떤 화면에서도 접근이 가능합니다. 이러한 경우, Up 버튼을 누르면 Back 버튼과 동일하게
+참조하는 화면으로 돌아가게 됩니다.</p>
+<h4>화면 내에서 뷰 변경</h4>
+<p>화면의 뷰 옵션 변경은 Up 또는 Back 버튼의 동작을 변경하지 않습니다. 이는 화면이 앱 계층 구조 내에서 여전히 동일한 위치에
있고, 어떠한 탐색 기록도 새로 생성되지 않기 때문입니다.</p>
<p>이러한 뷰 변경의 예는 다음과 같습니다.</p>
<ul>
@@ -70,21 +70,21 @@ page.image=/design/media/navigation_between_siblings_gmail.png
항목으로 직접 이동할 수 있도록 지원하는 것이 바람직한
경우도 있습니다. 예를 들어 Gmail의 대화에서 왼쪽 또는 오른쪽으로 간단하게 스와이프하여 동일한 받은 편지함에 있는 신규 또는 이전 메일을
볼 수 있습니다. 화면 내에서 뷰를 변경하는 것과 마찬가지로,
-탐색은 위로 또는 뒤로 버튼의 동작을 바꾸지 않습니다.</p>
+탐색은 Up 또는 Back 버튼의 동작을 바꾸지 않습니다.</p>
<img src="{@docRoot}design/media/navigation_between_siblings_gmail.png">
<p>하지만 참조 목록으로 같이
묶여 있지 않은 연관된 상세 뷰 사이를 탐색할 때는 주목할 만한 예외적인 상황이 발생합니다. 예를 들어, Play Store에서
동일한 개발자가 만든 여러 앱 또는 동일한 아티스트의 여러 앨범을 탐색하는 경우가 그렇습니다. 이러한 경우, 링크를 따라갈 때마다
-기록이 생성되므로, 뒤로 버튼을 누르면 이전에 본 화면으로 이동합니다. 위로 버튼을 누르면 계속해서 이러한 연관된 화면을
+기록이 생성되므로, Back 버튼을 누르면 이전에 본 화면으로 이동합니다. Up 버튼을 누르면 계속해서 이러한 연관된 화면을
거치지 않고 가장 최근에 본 컨테이너 화면으로 이동합니다.</p>
<img src="{@docRoot}design/media/navigation_between_siblings_market1.png">
<p>상세
-뷰에 대한 지식을 바탕으로 더욱 스마트한 위로 버튼 동작을 구현할 수 있습니다. 위에서 설명한 Play Store 예를 확장하여 사용자가
-마지막으로 본 도서에서 해당 도서를 각색한 영화의 세부 정보 화면으로 이동했다고 가정해 봅니다. 그러한 경우, 위로 버튼을 누르면 사용자가 이전에 탐색한 적이 없는
+뷰에 대한 지식을 바탕으로 더욱 스마트한 Up 버튼 동작을 구현할 수 있습니다. 위에서 설명한 Play Store 예를 확장하여 사용자가
+마지막으로 본 도서에서 해당 도서를 각색한 영화의 세부 정보 화면으로 이동했다고 가정해 봅니다. 그러한 경우, Up 버튼을 누르면 사용자가 이전에 탐색한 적이 없는
컨테이너(영화)로 이동할 수 있습니다.</p>
<img src="{@docRoot}design/media/navigation_between_siblings_market2.png">
@@ -95,22 +95,22 @@ page.image=/design/media/navigation_between_siblings_gmail.png
있는 화면으로 바로 이동할 수 있게 할 수 있습니다. 예를 들어, Gmail의 받은 편지함 위젯과 새 메시지 알림은
모두 받은 편지함 화면을 건너뛰고 사용자가 해당 메일로 바로 이동할 수 있게 해줍니다.</p>
-<p>이러한 두 경우 모두 위로 버튼을 다음과 같이 처리합니다.</p>
+<p>이러한 두 경우 모두 Up 버튼을 다음과 같이 처리합니다.</p>
<ul>
<li><em>일반적으로 목적지 화면이
-앱 내의 특정 화면에서 출발한 경우</em>, 위로 버튼은 해당 화면으로 이동해야 합니다.</li>
-<li><em>그 외의 경우</em>, 위로 버튼은 앱의 최상위("홈") 화면으로 이동해야 합니다.</li>
+앱 내의 특정 화면에서 출발한 경우</em>, Up 버튼은 해당 화면으로 이동해야 합니다.</li>
+<li><em>그 외의 경우</em>, Up 버튼은 앱의 최상위("홈") 화면으로 이동해야 합니다.</li>
</ul>
-<p>뒤로 버튼의 경우,
+<p>Back 버튼의 경우,
앱의 최상위 화면으로 이동하는 완전한 상위 탐색 경로를 태스크의 백 스택에 삽입하여 탐색을 더욱 예측 가능하게 만들어야 합니다. 이는 앱에 어떻게 진입했는지 잊어버린
사용자가 앱에서 나가기
전에 앱의 최상위 화면으로 이동할 수 있게 해줍니다.</p>
<p>예를 들어 Gmail의 홈 화면 위젯은 메일 작성
-화면으로 바로 진입할 수 있는 버튼을 제공합니다. 메일 작성 화면에서 위로 또는
-뒤로 버튼을 누르면 받은 편지함으로 이동하게 되고, 받은 편지함에서 뒤로 버튼을 누르면 홈으로 돌아가게 됩니다.</p>
+화면으로 바로 진입할 수 있는 버튼을 제공합니다. 메일 작성 화면에서 Up 또는
+Back 버튼을 누르면 받은 편지함으로 이동하게 되고, 받은 편지함에서 Back 버튼을 누르면 홈으로 돌아가게 됩니다.</p>
<img src="{@docRoot}design/media/navigation_from_outside_back.png">
@@ -118,20 +118,20 @@ page.image=/design/media/navigation_between_siblings_gmail.png
<p>앱이 동시에 다양한 이벤트 정보를 제공해야 하는 경우, 사용자를 틈새 화면(interstitial screen)으로 이동하게 하는
단일 알림을 사용할 수 있습니다. 이 화면은
-이러한 이벤트를 요약하고, 사용자가 앱을 세부적으로 탐색할 수 있는 경로를 제공합니다. 이러한 스타일의 알림을 <em>간접 알림</em>이라고
-합니다.</p>
+이러한 이벤트를 요약하고, 사용자가 앱을 세부적으로 탐색할 수 있는 경로를 제공합니다. 이러한 스타일의 알림을
+<em>간접 알림</em>이라고 합니다.</p>
<p>기본(직접) 알림과 달리, 간접 알림의
-틈새 화면에서 뒤로 버튼을 누르면 백 스택에 다른 화면이
+틈새 화면에서 Back 버튼을 누르면 백 스택에 다른 화면이
추가되지 않고 알림이 트리거된 지점으로 사용자를 이동시킵니다. 사용자가
-틈새 화면에서 앱으로 들어가면, 위로 버튼 및 뒤로 버튼은 위에서 설명한 바와 같이 틈새 화면으로 돌아가지 않고, 기본 알림과 마찬가지로 앱 내에서
+틈새 화면에서 앱으로 들어가면, Up 버튼 및 Back 버튼은 위에서 설명한 바와 같이 틈새 화면으로 돌아가지 않고, 기본 알림과 마찬가지로 앱 내에서
탐색을 수행합니다.</p>
<p>예를 들어 Gmail을 사용 중인 사용자가 캘린더로부터 간접 알림을 받았다고 가정해 봅니다. 해당
알림을 터치하면 틈새 화면이 열립니다. 이 화면에는 다른
-여러 이벤트에 대한 알림도 표시됩니다. 틈새 화면에서 뒤로 버튼을 터치하면 Gmail로 돌아갑니다. 특정
+여러 이벤트에 대한 알림도 표시됩니다. 틈새 화면에서 Back 버튼을 터치하면 Gmail로 돌아갑니다. 특정
이벤트를 터치하면 사용자를 틈새 화면에서 나오게 하여
-해당 이벤트의 세부 정보를 보여주는 완전한 캘린더 앱으로 이동하게 됩니다. 이벤트 세부 정보 화면에서 위로 버튼과 뒤로 버튼을 누르면 캘린더의 최상위 뷰로 이동하게 됩니다.</p>
+해당 이벤트의 세부 정보를 보여주는 완전한 캘린더 앱으로 이동하게 됩니다. 이벤트 세부 정보 화면에서 Up 버튼과 Back 버튼을 누르면 캘린더의 최상위 뷰로 이동하게 됩니다.</p>
<img src="{@docRoot}design/media/navigation_indirect_notification.png">
@@ -144,20 +144,20 @@ Talk는 친구가 화상 채팅에 참여하도록 보낸
초대를 사용자에게 알리기 위해 이러한 스타일의 알림을 사용하며, 이 초대는 몇 초 후에 자동으로 만료됩니다.</p>
<p>탐색 동작 측면에서, 팝업 알림은 간접
-알림의 틈새 화면 동작을 상당히 많이 따릅니다. 뒤로 버튼을 누르면 팝업 알림이 해제됩니다. 사용자가 팝업을
-통해 앱으로 이동하면, 위로 및 뒤로 버튼은 기본 알림의 규칙에 따라 앱 내에서
+알림의 틈새 화면 동작을 상당히 많이 따릅니다. Back 버튼을 누르면 팝업 알림이 해제됩니다. 사용자가 팝업을
+통해 앱으로 이동하면, Up 및 Back 버튼은 기본 알림의 규칙에 따라 앱 내에서
탐색합니다.</p>
<img src="{@docRoot}design/media/navigation_popup_notification.png">
<h2 id="between-apps">앱 간 탐색</h2>
-<p>Android 시스템의 기본이 되는 강점 중 하나는 앱이
-다른 앱을 실행할 수 있다는 점이며, 이로 인해 사용자는 한 앱에서 다른 앱으로 직접 이동할 수 있습니다. 예를 들어, 사진을 캡처해야 하는
-앱은 카메라 앱을 작동시킬 수 있으며, 카메라 앱은 사진을 해당 앱으로
-돌려줍니다. 이러한 기능은 개발자와 사용자 모두에게 매우 유용합니다. 왜냐하면 개발자는 쉽게 다른 앱의
-코드를 활용할 수 있고, 사용자는 흔히 수행하는
-작업을 일관된 환경으로 즐길 수 있기 때문입니다.</p>
+<p>Android 시스템의 본질적인 강점 중 하나는 앱이
+다른 앱을 실행할 수 있다는 점이며, 이로 인해 사용자는 한 앱에서 다른 앱으로 직접 이동할 수 있습니다. 예를 들어,
+사진을 캡처해야 하는 앱은 카메라 앱을 작동시킬 수 있으며, 카메라 앱은 사진을
+해당 앱으로 돌려줍니다. 이러한 기능은 개발자와 사용자 모두에게 매우 유용합니다.
+왜냐하면 개발자는 쉽게 다른 앱의 코드를 활용할 수 있고, 사용자는 흔히 수행하는 작업을 일관된 환경으로
+즐길 수 있기 때문입니다.</p>
<p>앱 간 탐색을 이해하려면 아래에서
설명하는 Android 프레임워크 동작을 알아야 합니다.</p>
@@ -179,9 +179,9 @@ Talk는 친구가 화상 채팅에 참여하도록 보낸
<h4>예: "공유하기"를 지원하는 앱 간에 탐색하기</h4>
-<p>액티비티, 태스크, 인텐트가 어떻게 같이 동작하는지 이해하려면 한 앱이 다른 앱을 사용하여 콘텐츠
-공유를 어떻게 가능하게 하는지 생각해 보세요. 예를 들어, 홈에서 Play Store 앱을 실행하면
-새로운 태스크 A가 시작됩니다(아래 그림 참조). Play Store에서 탐색하다가 홍보 도서의 세부 정보를
+<p>액티비티, 태스크, 인텐트가 어떻게 같이 동작하는지 이해하려면 앱이 어떻게 사용자가 다른 앱을 사용하여 콘텐츠를
+공유할 수 있도록 하는지 생각해 보세요. 예를 들어, 홈에서 Play 스토어 앱을 실행하면 새로운 태스크
+A가 시작됩니다(아래 그림 참조). Play 스토어에서 탐색하다가 홍보 도서의 세부 정보를
보기 위해 터치하면, 다른 액티비티를 추가하여 태스크를 연장하는 방식으로 사용자는 동일한 태스크에 머물게 됩니다. 공유하기
작업을 트리거하면 공유하기 인텐트를 처리하도록
등록된 액티비티(다양한 앱에서 제공)가 나열된 목록을 보여주는 대화 상자가 표시됩니다.</p>
@@ -192,15 +192,15 @@ Talk는 친구가 화상 채팅에 참여하도록 보낸
태스크 A의 연장으로 Gmail의 메일 작성 액티비티가 추가됩니다. Gmail의 백그라운드에서 실행되는 자체적인 태스크가 있을 경우, 해당 태스크는 아무런
영향도 받지 않습니다.</p>
-<p>메일 작성 액티비티에서 메시지를 보내거나 뒤로 버튼을 터치하면, 사용자는
-도서 세부 정보 액티비티로 돌아가게 됩니다. 뒤로 버튼을 연이어 터치하면 Play
+<p>메일 작성 액티비티에서 메시지를 보내거나 Back 버튼을 터치하면, 사용자는
+도서 세부 정보 액티비티로 돌아가게 됩니다. Back 버튼을 연이어 터치하면 Play
Store에서 탐색한 페이지로 되돌아가게 되어 결국에는 홈 화면에 이르게 됩니다.</p>
<img src="{@docRoot}design/media/navigation_between_apps_back.png">
-<p>하지만 사용자가 메일 작성 액티비티에서 위로 버튼을 터치하는 것은
+<p>하지만 사용자가 메일 작성 액티비티에서 Up 버튼을 터치하는 것은
Gmail에 남아 있고자 하는 의지를 보이는 것입니다. 따라서, 이 경우 Gmail의 대화 목록 액티비티가 표시되고, 새로운 태스크 B가 생성됩니다. 새로운 태스크는
-항상 홈에 기반을 두고 있기 때문에, 대화 목록에서 뒤로 버튼을 터치하면 홈으로 되돌아가게 됩니다.</p>
+항상 홈에 기반을 두고 있기 때문에, 대화 목록에서 Back 버튼을 터치하면 홈으로 되돌아가게 됩니다.</p>
<img src="{@docRoot}design/media/navigation_between_apps_up.png">
@@ -208,6 +208,6 @@ Gmail에 남아 있고자 하는 의지를 보이는 것입니다. 따라서,
최근 앱 화면을 통해). Gmail에 이미 백그라운드에서 실행 중인 자체적인 태스크가 있을 경우,
해당 태스크는 태스크 B로 대체됩니다. 이전 컨텍스트는 사용자의 새로운 목적에 따라 제거됩니다.</p>
-<p>앱 계층 구조 내의 액티비티에서 인텐트를 처리하도록 앱에서 등록하는 경우, 위로 탐색을 지정하는 방법에 대한 지침을 확인하려면
+<p>앱 계층 구조 내의 액티비티에서 인텐트를 처리하도록 앱에서 등록하는 경우, Up 탐색을 지정하는 방법에 대한 지침을 확인하려면
<a href="#into-your-app">홈 화면 위젯 및
알림을 통한 앱 탐색</a>을 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/distribute/index.jd b/docs/html-intl/intl/ko/distribute/index-ko.jd
index 1765673ea87a..1765673ea87a 100644
--- a/docs/html-intl/intl/ko/distribute/index.jd
+++ b/docs/html-intl/intl/ko/distribute/index-ko.jd
diff --git a/docs/html-intl/intl/ko/guide/components/activities.jd b/docs/html-intl/intl/ko/guide/components/activities.jd
new file mode 100644
index 000000000000..001982f6f63c
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/activities.jd
@@ -0,0 +1,756 @@
+page.title=작업
+page.tags=activity,intent
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Creating">액티비티 생성하기</a>
+ <ol>
+ <li><a href="#UI">사용자 인터페이스 구현하기</a></li>
+ <li><a href="#Declaring">매니페스트에서 액티비티 선언하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#StartingAnActivity">액티비티 시작하기</a>
+ <ol>
+ <li><a href="#StartingAnActivityForResult">결과에 대한 액티비티 시작하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#ShuttingDown">액티비티 종료하기</a></li>
+ <li><a href="#Lifecycle">액티비티 수명 주기 관리하기</a>
+ <ol>
+ <li><a href="#ImplementingLifecycleCallbacks">수명 주기 콜백 구현하기</a></li>
+ <li><a href="#SavingActivityState">액티비티 상태 저장하기</a></li>
+ <li><a href="#ConfigurationChanges">구성 변경 처리하기</a></li>
+ <li><a href="#CoordinatingActivities">액티비티 조정하기</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.app.Activity}</li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+ <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업 및 백
+스택</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>{@link android.app.Activity}는 일종의 애플리케이션 구성 요소로서,
+사용자와 상호작용할 수 있는 화면을 제공하여 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기 등의 일을 할 수
+있습니다. 액티비티마다 창이 하나씩 주어져 이곳에 사용자 인터페이스를 끌어올 수 있습니다. 이 창은
+일반적으로 화면을 가득 채우지만, 작은 창으로 만들어 다른 창 위에 띄울 수도
+있습니다.</p>
+
+<p> 하나의 애플리케이션은 보통 여러 개의 액티비티가 느슨하게 서로 묶여 있는 형태로
+구성됩니다. 통상 한 애플리케이션 내에서 하나의 액티비티가 "주요" 액티비티로 지정되며,
+사용자가 이 애플리케이션을 처음 실행할 때 이 액티비티가 사용자에게 표시됩니다. 그런 후
+각각의 액티비티는 여러 가지 작업을 수행하기 위해 또 다른 액티비티를 시작할 수 있습니다. 새로운
+액티비티가 시작될 때마다 이전 액티비티는 중단되지만 시스템은 해당 액티비티를
+스택("백 스택")에 보존합니다. 새로운 액티비티가 시작되면, 이것이 백 스택 위로 밀려와 사용자의
+시선을 끕니다. 백 스택은 기본적인 "후입선출" 방식을 지키므로,
+사용자가 현재 액티비티를 끝내고 <em>뒤로</em> 버튼을 누르면 해당 액티비티가
+스택에서 튀어나와(소멸되고) 이전 액티비티를 재개합니다 (백 스택은
+<a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업
+및 백 스택</a> 문서에서 상세하게 논의합니다).</p>
+
+<p>한 액티비티가 새로운 액티비티의 시작으로 인해 중단된 경우, 이 상태 변경은
+액티비티의 수명 주기 콜백 메서드를 통해 알려집니다.
+액티비티가 시스템 액티비티를 생성, 중단, 재시작, 제거하는 등의 상태 변화로 인해 받을 수 있는 콜백 메서드는 여러 가지가 있습니다.
+
+ 각 콜백은 상태 변화에 알맞은 특정 작업을 수행할 기회를 제공합니다.
+ 예를 들어 액티비티가 중단되면 네트워크 또는 데이터베이스 연결과 같이
+큰 개체는 모두 해제해야 합니다. 액티비티가 재개되면, 필요한 리소스를
+다시 획득하여 중단된 작업을 재개할 수 있습니다. 이러한 상태 전환은
+모두 액티비티 수명 주기의 일부입니다.</p>
+
+<p>이 문서의 남은 부분에서는 다양한 액티비티 상태 사이의 전환을 적절히 관리할 수 있도록 액티비티 수명 주기가 작동하는 방식을 자세히 논하는 등,
+액티비티를 구축하고 사용하는 기본적 방법을
+설명합니다.</p>
+
+
+
+<h2 id="Creating">액티비티 생성하기</h2>
+
+<p>액티비티를 생성하려면 {@link android.app.Activity}의 하위 클래스(또는 이의
+기존 하위 클래스)를 생성해야 합니다. 하위 클래스에서는
+액티비티 생성, 중단, 재개, 소멸 시기 등과 같은
+수명 주기의 다양한 상태 간 액티비티가 전환될 때 시스템이 호출하는 콜백 메서드를 구현해야 합니다. 가장 중요한 두 가지 콜백 메서드는
+다음과 같습니다.</p>
+
+<dl>
+ <dt>{@link android.app.Activity#onCreate onCreate()}</dt>
+ <dd>이 메서드는 반드시 구현해야 합니다. 시스템은 액티비티를 생성할 때 이것을 호출합니다.
+ 구현하는 중에 액티비티의 필수 구성 요소를 초기화해야
+합니다.
+ 무엇보다도 중요한 점은, 바로 여기서 {@link android.app.Activity#setContentView
+ setContentView()}를 호출해야 액티비티의 사용자 인터페이스 레이아웃을 정의할 수 있다는 점입니다.</dd>
+ <dt>{@link android.app.Activity#onPause onPause()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 사용자가 액티비티를 떠난다는
+첫 번째 신호입니다(다만 이것이 항상 액티비티가 소멸 중이라는 뜻은 아닙니다). 현재 사용자 세션을 넘어서
+지속되어야 하는 변경 사항을 커밋하려면 보통 이곳에서 해아 합니다(사용자가
+돌아오지 않을 수 있기 때문입니다).</dd>
+</dl>
+
+<p>여러 액티비티 사이에서 원활한 사용자 경험을 제공하고, 액티비티 중단이나 심지어
+소멸을 초래할 수도 있는 예상치 못한 간섭을 처리하기 위해 사용해야 하는 다른 수명 주기
+콜백 메서드도 여러 가지 있습니다. 모든 수명 주기 콜백 메서드는 나중에
+<a href="#Lifecycle">액티비티 수명 주기 관리</a> 섹션에서 자세히 논의할 것입니다.</p>
+
+
+
+<h3 id="UI">사용자 인터페이스 구현하기</h3>
+
+<p> 한 액티비티에 대한 사용자 인터페이스는 보기 계층&mdash;즉,
+{@link android.view.View} 클래스에서 파생된 개체가 제공합니다. 각 보기는 액티비티 창 안의 특정한 직사각형 공간을
+ 제어하며 사용자 상호 작용에 대응할 수 있습니다. 예를 들어, 어떤 보기는 사용자가 터치하면
+작업을 시작하는 버튼일 수 있습니다.</p>
+
+<p>Android는 레이아웃을 디자인하고 정리하는 데 사용할 수 있도록 여러 가지 보기를 미리 만들어
+제공합니다. "위젯"이란 화면에 시각적(이자 대화형) 요소를 제공하는 보기입니다. 예를 들어
+버튼, 텍스트 필드, 확인란이나 그저 하나의 이미지일 수도 있습니다. "레이아웃"은 선형 레이아웃, 격자형 레이아웃, 상대적 레이아웃과 같이 하위 레이아웃에 대해 독특한 레이아웃 모델을 제공하는 {@link
+android.view.ViewGroup}에서 파생된
+보기입니다. 또한, {@link android.view.View}와
+{@link android.view.ViewGroup} 클래스(또는 기존 하위 클래스)의 아래로 내려가서 위젯과 레이아웃을 생성하고
+이를 액티비티 레이아웃에 적용할 수 있습니다.</p>
+
+<p>보기를 사용하여 레이아웃을 정의하는 가장 보편적인 방식은 애플리케이션 리소스에 저장된
+XML 레이아웃 파일을 사용하는 것입니다. 이렇게 하면 액티비티의 동작을 정의하는
+소스 코드와 별개로 사용자 인터페이스 디자인을 유지할 수 있습니다.
+{@link android.app.Activity#setContentView(int) setContentView()}로 액티비티의 UI로서 레이아웃을 설정하고,
+해당 레이아웃의 리소스 ID를 전달할 수 있습니다. 그러나 액티비티 코드에 새로운 {@link android.view.View}를 생성하고
+ 새로운 {@link
+android.view.View}를 {@link android.view.ViewGroup}에 삽입하여 보기 계층을 구축한 뒤 루트
+{@link android.view.ViewGroup}을 {@link android.app.Activity#setContentView(View)
+setContentView()}에 전달해도 해당 레이아웃을 사용할 수 있습니다.</p>
+
+<p>사용자 인터페이스 생성에 관한 정보는 <a href="{@docRoot}guide/topics/ui/index.html">사용자 인터페이스</a> 문서를 참조하십시오.</p>
+
+
+
+<h3 id="Declaring">매니페스트에서 액티비티 선언하기</h3>
+
+<p>시스템에서 액티비티에 액세스할 수 있게 하려면 이를 매니페스트 파일에서
+선언해야만 합니다. 액티비티를 선언하려면 매니페스트 파일을 열고 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> 요소를
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+요소의 하위 항목으로 추가합니다. 예:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;application ... &gt;
+ &lt;activity android:name=".ExampleActivity" /&gt;
+ ...
+ &lt;/application ... &gt;
+ ...
+&lt;/manifest &gt;
+</pre>
+
+<p>액티비티 레이블, 액티비티 아이콘 또는 액티비티 UI 스타일용 테마와 같이
+이 요소에 포함할 수 있는 속성이 여러 가지 있습니다.
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a>
+ 속성이 유일한 필수 속성입니다. 이것이 액티비티의 클래스 이름을 지정합니다. 일단
+ 애플리케이션을 게시하고 나면 이 이름을 변경해서는 안 됩니다. 이름을 변경하면
+애플리케이션 바로 가기와 같은 일부 기능이 고장 날 수 있습니다(블로그 게시물의 <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">바꿀 수 없는
+항목</a>을 참조하십시오).</p>
+
+<p>매니페스트에서 액티비티를 선언하는 것에 관한 자세한 정보는 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> 요소
+ 참고 자료를 참조하십시오.</p>
+
+
+<h4>인텐트 필터 사용하기</h4>
+
+<p><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> 요소 또한 여러 가지 인텐트 필터를 지정할 수 있습니다. 다른 애플리케이션 구성 요소가 이를 활성화하는 방법을 선언하기 위해 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>를 사용하는
+것입니다.</p>
+
+<p>Android SDK 도구를 사용하여 새 애플리케이션을 생성하는 경우, 개발자를 위해
+생성되어 있는 스텁 액티비티에 자동으로 인텐트 필터가 포함되어 있어 "주요" 동작에
+응답하는 액티비티를 선언하며, 이는 "시작 관리자" 범주에 배치해야 합니다. 인텐트 필터는 다음과
+같은 형태를 띱니다.</p>
+
+<pre>
+&lt;activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> 요소는 이것이 애플리케이션으로 가는 "주요" 진입 지점이라는 것을 나타냅니다. <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> 요소는 이 액티비티가 시스템의
+애플리케이션 시작 관리자에 목록으로 나열되어야 한다는 것을 나타냅니다(사용자가 이 액티비티를 시작할 수 있도록 해줌).</p>
+
+<p>애플리케이션이 자체 포함 방식이기를 원하고 다른 애플리케이션이 이
+애플리케이션의 액티비티를 활성화하도록 허용하지 않고자 하면, 달리 인텐트 필터가 더 필요하지 않습니다. "주요" 동작과 "시작 관리자" 범주가 있는
+액티비티는 하나뿐이어야 합니다(이전 예시 참조). 다른 애플리케이션에서
+사용할 수 없게 하고자 하는 액티비티에는 인텐트 필터가 있으면 안 됩니다.
+이러한 액티비티는 명시적인 인텐트를 사용해 직접 시작할 수 있습니다(이 내용은 다음 섹션에서 논의).</p>
+
+<p>그러나, 액티비티가 다른 애플리케이션(및 본인의 애플리케이션)에서
+전달된 암시적 인텐트에 응답하도록 하려면 액티비티에 추가로 인텐트 필터를 정의해야만
+합니다. 응답하게 하고자 하는 각 인텐트 유형별로
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> 요소를 포함하는 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a>를 하나씩 포함시켜야 하며, 선택 사항으로 <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> 요소 및/또는 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> 요소를 포함시킬 수 있습니다. 이와 같은 요소는 액티비티가 응답할 수 있는 인텐트의 유형을
+나타냅니다.</p>
+
+<p>액티비티가 인텐트에 응답하는 방식에 관한 자세한 정보는 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a>
+문서를 참조하십시오.</p>
+
+
+
+<h2 id="StartingAnActivity">액티비티 시작하기</h2>
+
+<p>다른 액티비티를 시작하려면 {@link android.app.Activity#startActivity
+ startActivity()}를 호출한 다음 이에 시작하고자 하는 액티비티를 설명하는 {@link android.content.Intent}를
+전달하면 됩니다. 인텐트는 시작하고자 하는 액티비티를 정확히 나타내거나, 수행하고자 하는 작업의
+유형을 설명하는 것입니다(시스템이 적절한 액티비티를 선택하며,
+이는
+ 다른 애플리케이션에서 가져온 것일 수도 있습니다). 인텐트는 소량의 데이터를 운반하여 시작된 액티비티에서
+ 사용할 수 있습니다.</p>
+
+<p>본인의 애플리케이션 안에서 작업하는 경우에는, 알려진 액티비티를 시작하기만 하면 되는 경우가 잦습니다.
+ 이렇게 하려면 시작하고자 하는 액티비티를 명시적으로 정의하는 인텐트를 클래스 이름을
+사용하여 생성하면 됩니다. 예를 들어, 다음은 한 액티비티가 {@code
+SignInActivity}라는 이름의 다른 액티비티를 시작하는 방법입니다.</p>
+
+<pre>
+Intent intent = new Intent(this, SignInActivity.class);
+startActivity(intent);
+</pre>
+
+<p>그러나, 애플리케이션이 다른 몇 가지 동작을 수행하고자 할 수도 있습니다. 예를 들어 이메일 보내기, 문자
+메시지 보내기 또는 상태 업데이트 등을 액티비티의 데이터를 사용하여 수행하는 것입니다. 이 경우, 본인의 애플리케이션에
+그러한 동작을 수행할 자체 액티비티가 없을 수도 있습니다. 따라서 기기에 있는 다른 애플리케이션이
+제공하는 액티비티를 대신 활용하여 동작을 수행하도록 할 수 있습니다. 바로 이 부분에서
+인텐트의 진가가 발휘됩니다. 수행하고자 하는 동작을 설명하는 인텐트를 생성하면
+시스템이 적절한 액티비티를
+ 다른 애플리케이션에서 시작하는 것입니다. 해당 인텐트를
+ 처리할 수 있는 액티비티가 여러 개 있는 경우, 사용자가 어느 것을 사용할지 선택합니다. 예를
+ 들어 사용자가 이메일 메시지를 보낼 수 있게 하려면, 다음과 같은 인텐트를
+생성하면 됩니다.</p>
+
+<pre>
+Intent intent = new Intent(Intent.ACTION_SEND);
+intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
+startActivity(intent);
+</pre>
+
+<p>인텐트에 추가된 {@link android.content.Intent#EXTRA_EMAIL} 추가 사항은 이메일이 전송되어야 할 이메일 주소의
+ 문자열 배열입니다. 이메일 애플리케이션이 이 인텐트에
+응답하면, 애플리케이션은 추가 사항이 제공한 문자열 배열을 읽어낸 다음 이를 이메일 작성 양식의
+ "수신" 필드에 배치합니다. 이 상황에서 이메일 애플리케이션의 액티비티가 시작되고 사용자가
+ 작업을 끝내면 본인의 액티비티가 재개되는 것입니다.</p>
+
+
+
+
+<h3 id="StartingAnActivityForResult">결과에 대한 액티비티 시작하기</h3>
+
+<p>때로는 시작한 액티비티에서 결과를 받고 싶을 수도 있습니다. 그런 경우,
+ ({@link android.app.Activity#startActivity
+ startActivity()} 대신) {@link android.app.Activity#startActivityForResult
+ startActivityForResult()}를 호출해서 액티비티를 시작합니다. 그런 다음 후속 액티비티에서 결과를
+받으려면, {@link android.app.Activity#onActivityResult onActivityResult()} 콜백
+ 메서드를 구현합니다. 해당 후속 액티비티가 완료되면, 이것이 {@link
+android.content.Intent} 형식으로 결과를 {@link android.app.Activity#onActivityResult onActivityResult()}
+ 메서드에 반환합니다.</p>
+
+<p>예를 들어 사용자가 연락처 중에서 하나를 고를 수 있도록 하고 싶을 수 있습니다.
+즉 여러분의 액티비티가 해당 연락처의 정보로 무언가 할 수 있도록 하는 것입니다. 그와 같은 인텐트를 생성하고 결과를 처리하려면
+다음과 같이 하면 됩니다.</p>
+
+<pre>
+private void pickContact() {
+ // Create an intent to "pick" a contact, as defined by the content provider URI
+ Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
+ startActivityForResult(intent, PICK_CONTACT_REQUEST);
+}
+
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
+ if (resultCode == Activity.RESULT_OK &amp;&amp; requestCode == PICK_CONTACT_REQUEST) {
+ // Perform a query to the contact's content provider for the contact's name
+ Cursor cursor = getContentResolver().query(data.getData(),
+ new String[] {Contacts.DISPLAY_NAME}, null, null, null);
+ if (cursor.moveToFirst()) { // True if the cursor is not empty
+ int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
+ String name = cursor.getString(columnIndex);
+ // Do something with the selected contact's name...
+ }
+ }
+}
+</pre>
+
+<p>이 예시는 액티비티 결과를 처리하기 위해 {@link
+android.app.Activity#onActivityResult onActivityResult()} 메서드에서 사용해야 할 기본 논리를
+ 나타낸 것입니다. 첫 번째 조건은 요청이 성공적인지 확인합니다. 요청에 성공했다면
+{@code resultCode}가 {@link android.app.Activity#RESULT_OK}가 됩니다. 또한, 이 결과가 응답하는 요청이
+알려져 있는지도 확인합니다. 이 경우에는 {@code requestCode}가
+{@link android.app.Activity#startActivityForResult
+startActivityForResult()}와 함께 전송된 두 번째 매개변수와 일치합니다. 여기서부터 코드가
+{@link android.content.Intent}({@code data} 매개변수)로 반환된 데이터를 쿼리하여 액티비티 결과를 처리합니다.</p>
+
+<p>그러면 {@link
+android.content.ContentResolver}가 콘텐츠 제공자에 대한 쿼리를 수행하고, 콘텐츠 제공자는 쿼리된 데이터를 읽을 수 있게 허용하는
+{@link android.database.Cursor}를 반환합니다. 자세한 내용은
+<a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a> 문서를 참조하십시오.</p>
+
+<p>인텐트 사용에 관한 자세한 정보는 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트
+ 필터</a>문서를 참조하십시오.</p>
+
+
+<h2 id="ShuttingDown">액티비티 종료하기</h2>
+
+<p>액티비티를 종료하려면 해당 액티비티의 {@link android.app.Activity#finish
+finish()} 메서드를 호출하면 됩니다.
+{@link android.app.Activity#finishActivity finishActivity()}를 호출하여 이전에 시작한 별도의 액티비티를 종료할 수도 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 대부분의 경우, 이와 같은 메서드를 사용하여 액티비티를 명시적으로
+종료해서는 안 됩니다. 다음 섹션에서 액티비티 수명 주기에 관해 논의한 바와 같이,
+Android 시스템이 액티비티의 수명을 대신 관리해주므로 직접 액티비티를 종료하지
+않아도 됩니다. 이와 같은 메서드를 호출하면 예상되는 사용자
+환경에 부정적인 영향을 미칠 수 있으며, 따라서 사용자가 액티비티의 이 인스턴스에 돌아오는 것을 절대 바라지 않는 경우에만
+사용해야 합니다.</p>
+
+
+<h2 id="Lifecycle">액티비티 수명 주기 관리하기</h2>
+
+<p>콜백 메서드를 구현하여 액티비티의 수명 주기를 관리하는 것은
+강력하고 유연한 애플리케이션 개발에
+대단히 중요한 역할을 합니다. 액티비티의 수명 주기는 다른 액티비티와의 관계,
+액티비티의 작업과 백 스택 등에 직접적으로 영향을 받습니다.</p>
+
+<p>액티비티는 기본적으로 세 가지 상태로 존재할 수 있습니다.</p>
+
+<dl>
+ <dt><i>재개됨</i></dt>
+ <dd>액티비티가 화면 전경에 있으며 사용자의 초점이 맞춰져 있습니다 (이 상태를 때로는
+"실행 중"이라고 일컫기도 합니다).</dd>
+
+ <dt><i>일시정지됨</i></dt>
+ <dd>다른 액티비티가 전경에 나와 있고 사용자의 시선을 집중시키고 있지만, 이 액티비티도 여전히 표시되어 있습니다. 다시 말해,
+다른 액티비티가 이 액티비티 위에 표시되어 있으며 해당 액티비티는 부분적으로 투명하거나
+전체 화면을 덮지 않는 상태라는 뜻입니다. 일시정지된 액티비티는 완전히 살아있지만({@link android.app.Activity}
+개체가 메모리에 보관되어 있고, 모든 상태 및 구성원 정보를 유지하며,
+창 관리자에 붙어 있는 상태로 유지됨), 메모리가 극히 부족한 경우 시스템이 중단시킬 수 있습니다.</dd>
+
+ <dt><i>정지됨</i></dt>
+ <dd>이 액티비티가 다른 액티비티에 완전히 가려진 상태입니다(액티비티가 이제
+"배경"에 위치함). 중단된 액티비티도 여전히 살아 있기는 마찬가지입니다({@link android.app.Activity}
+개체가 메모리에 보관되어 있고, 모든 상태와 구성원 정보를 유지하시만 창 관리자에 붙어 있지 <em>않음</em>
+). 그러나, 이는 더 이상 사용자에게 표시되지 않으며
+다른 곳에 메모리가 필요하면 시스템이 종료시킬 수 있습니다.</dd>
+</dl>
+
+<p>액티비티가 일시정지 또는 중단된 상태이면, 시스템이 이를 메모리에서 삭제할 수 있습니다. 이러기 위해서는
+종료를 요청하거나({@link android.app.Activity#finish finish()} 메서드를 호출) 단순히 이 액티비티의 프로세스를 중단시키면
+됩니다. 액티비티가 다시 열릴 때에는(종료 또는 중단된 후에) 처음부터 다시 생성해야
+합니다.</p>
+
+
+
+<h3 id="ImplementingLifecycleCallbacks">수명 주기 콜백 구현하기</h3>
+
+<p>위에서 설명한 바와 같이 액티비티가 여러 가지 상태를 오가며 전환되면, 이와 같은 내용이
+여러 가지 콜백 메서드를 통해 통지됩니다. 콜백 메서드는 모두 후크로서,
+액티비티 상태가 변경될 때 적절한 작업을 하기 위해 이를 재정의할 수 있습니다. 다음의 골격
+액티비티에는 기본 수명 주기 메서드가 각각 하나씩 포함되어 있습니다.</p>
+
+
+<pre>
+public class ExampleActivity extends Activity {
+ &#64;Override
+ public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // The activity is being created.
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onStart onStart()} {
+ super.onStart();
+ // The activity is about to become visible.
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onResume onResume()} {
+ super.onResume();
+ // The activity has become visible (it is now "resumed").
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onPause onPause()} {
+ super.onPause();
+ // Another activity is taking focus (this activity is about to be "paused").
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onStop onStop()} {
+ super.onStop();
+ // The activity is no longer visible (it is now "stopped")
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onDestroy onDestroy()} {
+ super.onDestroy();
+ // The activity is about to be destroyed.
+ }
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> 이와 같은 수명 주기 메서드를 구현하려면, 항상
+ 슈퍼클래스 구현을 호출한 다음에만 다른 작업을 시작할 수 있습니다(위의 예시 참조).</p>
+
+<p>이와 같은 메서드를 모두 합쳐 한 액티비티의 수명 주기 전체를 정의합니다. 이러한 메서드를 구현함으로써
+액티비티 수명 주기 내의 세 가지 중첩된 루프를 모니터링할 수 있습니다. </p>
+
+<ul>
+<li>한 액티비티의 <b>전체 수명</b>은 {@link
+android.app.Activity#onCreate onCreate()} 호출과 {@link
+android.app.Activity#onDestroy} 호출 사이를 말합니다. 액티비티는 {@link android.app.Activity#onCreate onCreate()}에서
+"전체" 상태(레이아웃 정의 등)의 설정을 수행한 다음 나머지 리소스를
+모두 {@link android.app.Activity#onDestroy}에 해제해야 합니다. 예를 들어,
+액티비티에 네트워크에서 데이터를 다운로드하기 위해 배경에서 실행 중인 스레드가 있는 경우, 이는
+해당 스레드를 {@link android.app.Activity#onCreate onCreate()}에서 생성한 다음 {@link
+android.app.Activity#onDestroy}에서 그 스레드를 중단할 수 있습니다.</li>
+
+<li><p>액티비티의 <b>가시적 수명</b>은 {@link
+android.app.Activity#onStart onStart()} 호출에서 {@link
+android.app.Activity#onStop onStop()} 호출 사이를 말합니다. 이 기간 중에는 사용자가 액티비티를 화면에서 보고 이와
+상호작용할 수 있습니다. 예컨대 {@link android.app.Activity#onStop onStop()}이 호출되어
+ 새 액티비티가 시작되면 이 액티비티는 더 이상 표시되지 않게 됩니다. 이와 같은 두 가지 메서드 중에서
+사용자에게 액티비티를 표시하는 데 필요한 리소스를 유지하면 됩니다. 예를 들어,
+{@link
+android.app.Activity#onStart onStart()}에서 {@link android.content.BroadcastReceiver}를 등록하고 UI에 영향을 미치는 변화를 모니터링하고
+{@link android.app.Activity#onStop onStop()}에서 등록을 해제하면 사용자는 여러분이 무엇을 표시하고 있는지 더 이상 볼 수
+없게 됩니다. 시스템은 액티비티의 전체 수명 내내 {@link android.app.Activity#onStart onStart()} 및 {@link
+android.app.Activity#onStop onStop()}을 여러 번 호출할 수 있으며, 이때
+액티비티는 사용자에게 표시되었다 숨겨지는 상태를 오가게 됩니다.</p></li>
+
+<li><p>액티비티의 <b>전경 수명</b>은 {@link
+android.app.Activity#onResume onResume()} 호출에서 {@link android.app.Activity#onPause
+onPause()} 호출 사이를 말합니다. 이 기간 중에는 이 액티비티가 화면에서 다른 모든 액티비티 앞에 표시되며 사용자 입력도
+여기에 집중됩니다. 액티비티는 전경에 나타났다 숨겨지는 전환을 자주 반복할 수 있습니다. 예를 들어
+, 기기가 절전 모드에 들어가거나 대화 상자가
+나타나면 {@link android.app.Activity#onPause onPause()}가 호출됩니다. 이 상태는 자주 전환될 수 있으므로, 이 두 가지 메서드의 코드는
+상당히 가벼워야 합니다. 그래야 전환이 느려 사용자를 기다리게 하는 일을 피할 수 있습니다.</p></li>
+</ul>
+
+<p>그림 1은 액티비티가 상태 사이에서 취할 수 있는 이와 같은 루프와 경로를 나타낸 것입니다.
+직사각형이 액티비티가 여러 상태 사이를 전환할 때 작업을 수행하도록
+구현할 수 있는 콜백 메서드를 나타냅니다. <p>
+
+<img src="{@docRoot}images/activity_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 액티비티 수명 주기입니다.</p>
+
+<p>같은 수명 주기 콜백 메서드가 표 1에 나열되어 있으며, 이 표는 각 콜백
+메서드를 더욱 상세하게 설명하며 액티비티의 전반적인
+수명 주기 내에서 각 메서드의 위치를 나타내기도 합니다. 여기에는 콜백 메서드가 완료된 다음
+시스템이 액티비티를 중단시킬 수 있는지 여부도 포함되어 있습니다.</p>
+
+<p class="table-caption"><strong>표 1.</strong> 액티비티 수명 주기
+콜백 메서드의 요약입니다.</p>
+
+<table border="2" width="85%" frame="hsides" rules="rows">
+<colgroup align="left" span="3"></colgroup>
+<colgroup align="left"></colgroup>
+<colgroup align="center"></colgroup>
+<colgroup align="center"></colgroup>
+
+<thead>
+<tr><th colspan="3">메서드</th> <th>설명</th> <th>완료 후 중단 가능?</th> <th>다음</th></tr>
+</thead>
+
+<tbody>
+<tr>
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
+ <td>액티비티가 처음 생성되었을 때 호출됩니다.
+ 이곳에서 일반적인 정적 설정을 모두 수행해야 합니다.
+즉 보기 생성, 목록에 데이터 바인딩하기 등을 말합니다. 이 메서드에는
+액티비티의 이전 상태가 캡처된 경우 해당 상태를 포함한
+번들 개체가 전달됩니다(이 문서 나중에 나오는 <a href="#actstate">액티비티 상태 저장하기</a>를 참조하십시오
+).
+ <p>이 뒤에는 항상 {@code onStart()}가 따라옵니다.</p></td>
+ <td align="center">아니요</td>
+ <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+ <td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart
+onRestart()}</code></td>
+ <td>액티비티가 중단되었다가 다시 시작되기 직전에
+호출됩니다.
+ <p>이 뒤에는 항상 {@code onStart()}가 따라옵니다.</p></td>
+ <td align="center">아니요</td>
+ <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td>
+ <td>액티비티가 사용자에게 표시되기 직전에 호출됩니다.
+ <p>액티비티가 전경으로 나오면 {@code onResume()}이 뒤에 따라오고,
+액티비티가 숨겨지면 {@code onStop()}이 뒤에 따라옵니다.</p></td>
+ <td align="center">아니요</td>
+ <td align="center">{@code onResume()} <br/>또는<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+ <td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td>
+ <td>액티비티가 시작되고 사용자와 상호 작용하기 직전에
+호출됩니다. 이 시점에서 액티비티는 액티비티
+스택의 맨 위에 있으며, 사용자 입력이 입력되고 있습니다.
+ <p>이 뒤에는 항상 {@code onPause()}가 따라옵니다.</p></td>
+ <td align="center">아니요</td>
+ <td align="center">{@code onPause()}</td>
+</tr>
+
+<tr>
+ <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td>
+ <td>시스템이 다른 액티비티를 재개하기 직전에
+호출됩니다. 이 메서드는 일반적으로 데이터를 유지하기 위해 저장되지 않은 변경 사항을
+커밋하는 데, 애니메이션을 비롯하여 CPU를 소모하는 기타 작업을 중단하는 등
+여러 가지 용도에 사용됩니다. 이 메서드는 무슨 일을 하든 매우 빨리 끝내야 합니다.
+이것이 반환될 때까지 다음 액티비티가 재개되지 않기 때문입니다.
+ <p>액티비티가 다시 전경으로 돌아오면 {@code onResume()}이 뒤에 따라오고
+액티비티가 사용자에게 보이지 않게 되면{@code onStop()}이 뒤에 따라옵니다.
+</td>
+ <td align="center"><strong style="color:#800000">예</strong></td>
+ <td align="center">{@code onResume()} <br/>또는<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td>
+ <td>액티비티가 더 이상 사용자에게 표시되지 않게 되면 호출됩니다. 이것은
+ 액티비티가 소멸되고 있기 때문에 일어날 수도 있고, 다른 액티비티
+(기존 것이든 새로운 것이든)가 재개되어 이것을 덮고 있기 때문일 수도 있습니다.
+ <p>액티비티가 다시 사용자와 상호 작용하면
+{@code onRestart()}가 뒤에 따라오고 액티비티가 사라지면
+{@code onDestroy()}가 뒤에 따라옵니다.</p></td>
+ <td align="center"><strong style="color:#800000">예</strong></td>
+ <td align="center">{@code onRestart()} <br/>또는<br/> {@code onDestroy()}</td>
+</tr>
+
+<tr>
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy
+onDestroy()}</code></td>
+ <td>액티비티가 소멸되기 전에 호출됩니다. 이것이 액티비티가 받는
+마지막 호출입니다. 이것이 호출될 수 있는 경우는 액티비티가
+완료되는 중이라서(누군가가 여기에 <code>{@link android.app.Activity#finish
+ finish()}</code>를 호출해서)일 수도 있고, 시스템이 공간을 절약하기 위해 액티비티의 이 인스턴스를 일시적으로 소멸시키는
+중이기 때문일 수도 있습니다. 이와 같은
+두 가지 시나리오는 <code>{@link
+ android.app.Activity#isFinishing isFinishing()}</code> 메서드로 구분할 수 있습니다.</td>
+ <td align="center"><strong style="color:#800000">예</strong></td>
+ <td align="center"><em>없음</em></td>
+</tr>
+</tbody>
+</table>
+
+<p>"완료 후 중단 가능?"이라는 레이블이 붙은 열은
+ 시스템이 <em>메서드가 반환된 후</em> 액티비티 코드의 다른 줄을 실행하지 않고도
+언제든 이 액티비티를 호스팅하는 프로세스를 중단시킬 수 있는지 여부를 나타냅니다. 다음 세 가지 메서드가 "예"로 표시되어 있습니다({@link
+android.app.Activity#onPause
+onPause()}, {@link android.app.Activity#onStop onStop()} 및 {@link android.app.Activity#onDestroy
+onDestroy()}). {@link android.app.Activity#onPause onPause()}가 세 가지 메서드 중에서
+첫 번째이므로, 액티비티가 생성되면 {@link android.app.Activity#onPause onPause()}는 프로세스가 <em>지워지기 전에</em>
+반드시 호출되는 마지막 메서드입니다.
+시스템이 비상 시에 메모리를 복구해야 할 경우, {@link
+android.app.Activity#onStop onStop()}와 {@link android.app.Activity#onDestroy onDestroy()}는
+호출되지 않을 수도 있습니다. 따라서, 중요한 영구적 데이터(사용자 편집 등)를 보관하기 위해 작성하는 경우에는 {@link android.app.Activity#onPause onPause()}를 사용해야
+합니다. 그러나, {@link android.app.Activity#onPause onPause()} 중에
+어느 정보를 유지해야 할지는 조심해서 선택해야 합니다. 이 메서드에 차단 절차가 있으면
+다음 액티비티로의 전환을 차단하고 사용자 경험을 느려지게 할 수 있기
+때문입니다.</p>
+
+<p> <b>중단 가능한</b> 열에 "아니요"로 표시된 메서드는 액티비티를 호스팅하는 프로세스를
+보호하여 호출된 즉시 중단되지 않도록 방지합니다. 따라서 액티비티는
+{@link android.app.Activity#onPause onPause()}가 반환되는 시기부터
+{@link android.app.Activity#onResume onResume()}이 호출되는 시기 사이에 중단시킬 수 있습니다. 다시 중단시킬 수 있는 상태가 되려면
+{@link android.app.Activity#onPause onPause()}가 다시 호출되어 반환되어야 합니다. </p>
+
+<p class="note"><strong>참고:</strong> 표 1에 나타난 이런 정의에
+따르면 엄밀히 말해 "중단 가능한" 것이 아닌 액티비티라도 시스템이 중단시킬 수는 있습니다. 다만 이것은 다른 리소스가 없는
+극단적인 상황에서만 발생합니다. 액티비티가 중단될 수 있는 시기가
+언제인지는 <a href="{@docRoot}guide/components/processes-and-threads.html">프로세스 및
+ 스레딩</a> 문서에서 보다 자세히 논의합니다.</p>
+
+
+<h3 id="SavingActivityState">액티비티 상태 저장하기</h3>
+
+<p><a href="#Lifecycle">액티비티 수명 주기 관리하기</a> 도입부에서는 액티비티가
+일시중지되거나
+중단되었더라도 액티비티의 상태는 그대로 유지된다고 잠시 언급한 바 있습니다. 이것은
+{@link android.app.Activity} 개체가 일시중지되거나 중단된 경우에도
+메모리 안에 그대로 보관되었기 때문에 가능합니다. 즉 이 액티비티의 구성원과 현재 상태에 대한 모든 정보가 아직 살아 있다는 뜻입니다. 따라서, 사용자가
+액티비티 내에서 변경한 모든 내용도 그대로 유지되어 액티비티가 전경으로
+돌아갈 때("재개"될 때) 그와 같은 변경 사항도 그대로 존재하게 됩니다.</p>
+
+<p>그러나 시스템이 메모리를 복구하기 위해 액티비티를 소멸시키는 경우에는 {@link
+android.app.Activity} 개체가 소멸되므로 시스템이 액티비티의 상태를 온전히 유지한 채로 간단하게 재개할 수 없게
+됩니다. 대신, 사용자가 다시 이 액티비티로 이동해 오면 시스템이 {@link android.app.Activity} 개체를
+다시 생성해야 합니다. 하지만, 사용자는 시스템이
+해당 액티비티를 소멸시켰다가 다시 생성했다는 것을 모릅니다.
+따라서 액티비티가 예전과 똑같을 것이라고 예상할 것입니다. 이런 상황에서는
+액티비티 상태에 관한 정보를 저장할 수 있는 추가 콜백 메서드
+{@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}를 구현하여 액티비티 상태에 관한 중요한 정보를 보존할 수 있습니다.</p>
+
+<p>시스템이 {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
+를 호출한 다음에 액티비티를 소멸되기 쉽게 만듭니다. 시스템은 {@link
+android.os.Bundle#putString putString()}와 {@link
+android.os.Bundle#putInt putInt()} 같은 메서드를 사용하여, 이 메서드에
+액티비티에 관한 정보를 이름-값 쌍으로 저장할 수 있는 {@link android.os.Bundle}을 전달합니다.
+ 그리고 시스템이 애플리케이션 프로세스를 지우고
+사용자가 액티비티로 다시 돌아오면, 시스템이 액티비티를 다시 생성하고
+{@link android.os.Bundle}을 {@link android.app.Activity#onCreate onCreate()}와 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}에게 전달합니다. 이들 메서드 중
+하나를 사용하여 {@link android.os.Bundle}에서 저장된 상태를 추출하고 액티비티 상태
+를 복원할 수 있습니다. 복구할 상태 정보가 없는 경우, 여러분에게 전달되는 {@link
+android.os.Bundle}은 null입니다(액티비티가 처음 생성되었을 때 이런 경우가
+발생합니다).</p>
+
+<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" />
+<p class="img-caption"><strong>그림 2.</strong> 액티비티의 상태가 온전한 채로 사용자의
+초점에 다시 돌아오는 데에는 두 가지 방식이 있습니다. 하나는 액티비티가 소멸되었다가 다시 생성되어 액티비티가
+이전에 저장된 상태를 복구해야 하는 경우, 다른 하나는 액티비티가 중단되었다가 재개되었으며
+액티비티 상태가 온전히 유지된 경우입니다.</p>
+
+<p class="note"><strong>참고:</strong> 상태를 저장할 필요가 없는 경우도 있으므로 액티비티가 소멸되기 전에 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}가 호출된다는 보장은 없습니다
+
+(예컨대 사용자가
+명시적으로
+액티비티를 닫기 위해 <em>뒤로</em> 버튼을 눌러서 액티비티를 떠날 때가 이에 해당합니다). 시스템이 {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}를 호출하는 경우, {@link
+android.app.Activity#onStop onStop()} 전에 호출하는 것이 일반적이며 {@link android.app.Activity#onPause
+onPause()} 전에 호출할 가능성도 높습니다.</p>
+
+<p>그러나 아무것도 하지 않고 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}를 구현하지 않더라도,
+{@link android.app.Activity} 클래스의 기본 구현 {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}가 일부 액티비티 상태를 복구합니다. 특히, 기본
+구현은 레이아웃에서 {@link
+android.view.View}가 나올 때마다 해당하는 {@link
+android.view.View#onSaveInstanceState onSaveInstanceState()} 메서드를 호출하고, 이 때문에 각 보기가 저장해야 하는 자체 관련 정보를 제공할 수
+있게 해줍니다. Android 프레임워크를 사용하는 위젯은 거의 대부분 이 메서드를
+필요에 따라 구현하므로, UI에 눈에 보이는 변경이 있으면 모두 자동으로 저장되며 액티비티를 다시
+생성하면 복구됩니다. 예를 들어, {@link android.widget.EditText} 위젯은 사용자가 입력한 모든 텍스트
+를 저장하고 {@link android.widget.CheckBox} 위젯은 확인 여부를 저장합니다.
+ 여러분이 해야 할 유일한 작업은 상태를 저장하고자 하는 각 위젯에 고유 ID(<a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>
+속성 포함)를 제공하는 것입니다. 위젯에 ID가 없으면 시스템이 그 위젯의 상태를
+저장할 수 없습니다.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<p>또한,
+{@link android.R.attr#saveEnabled android:saveEnabled} 속성을 {@code "false"}로 설정하거나
+{@link android.view.View#setSaveEnabled setSaveEnabled()} 메서드를 호출해서 레이아웃의 보기가 상태를 저장하지 못하도록 명시적으로 막을 수 있습니다. 보통은 이것을 비활성화해서는
+안 되지만, 액티비티 UI의 상태를 다르게 복구하고자 하는 경우 그렇게 할 수도 있습니다.</p>
+</div>
+</div>
+
+<p>{@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 기본 구현이 액티비티 UI의 유용한 정보를 저장하지만
+추가 정보를 저장하려면 이를 재설정해야 할 수도 있습니다.
+예를 들어, 액티비티 수명에서 변경된 구성원 값을 변경해야 할 수도 있습니다(
+UI에서 복구된 값과 상관관계가 있을 수 있지만 이런 UI 값을 보유한 구성원은 기본적으로 복구되지 않습니다
+).</p>
+
+<p>{@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 기본 구현이 UI 상태를 저장하는 데 도움이 되기 때문에,
+추가 상태 정보를 저장하기 위해 이 메서드를 재정의하려면
+작업을 하기 전에 항상{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}의 슈퍼클래스 구현
+을 호출해야 합니다. 이와 마찬가지로 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}를 재정의하는 경우, 이것의 슈퍼클래스 구현을 호출해야 하기도 합니다.
+이렇게 해야 기본 구현이 보기 상태를 복구할 수 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}의 호출이 보장되지 않으므로
+ 이것은 액티비티의 일시적 상태(UI의 상태
+)를 기록하는 데에만 사용하고, 영구 데이터를 보관하는 데 사용해서는 안 됩니다. 대신, 사용자가 액티비티를 떠날 때 영구적인 데이터(데이터베이스에 저장되어야
+하는 데이터 등)를 저장하려면 {@link
+android.app.Activity#onPause onPause()}를 사용해야 합니다.</p>
+
+<p>애플리케이션의 상태 저장 기능을 시험하는 좋은 방법은 기기를 회전해보고 화면 방향이
+바뀌는지 확인하는 것입니다. 화면 방향이 바뀌면 시스템은 액티비티를
+소멸시켰다가 다시 생성하여 새 화면 구성에서 이용할 수 있을지 모르는 대체
+리소스를 적용합니다. 이 이유 하나만으로도 액티비티가 다시 생성되었을 때 상태를
+완전히 복구할 수 있어야 한다는 점이 대단히 중요합니다. 사용자는 애플리케이션을 사용하면서 화면을
+자주 돌리기 때문입니다.</p>
+
+
+<h3 id="ConfigurationChanges">구성 변경 처리하기</h3>
+
+<p>몇몇 기기 구성은 런타임 중에 변경될 수 있습니다(예: 화면 방향, 키보드 가용성
+ 및 언어 등). 이러한 변경이 발생하면 Android는 실행 중인 액티비티를 다시 생성합니다
+(시스템이 {@link android.app.Activity#onDestroy}를 호출하고 즉시 {@link
+android.app.Activity#onCreate onCreate()}를 호출합니다). 이런 동작은
+여러분이 제공한 대체 리소스로 애플리케이션을 자동으로 다시 로딩함으로써 새로운 구성에 애플리케이션이 적응하는 것을 돕도록
+설계되었습니다
+(예: 다양한 화면 방향과 크기에 대한 다양한 레이아웃).</p>
+
+<p>액티비티를 적절히 설계하여 화면 방향 변경으로 인한 재시작을 감당할 수 있으며
+위에 설명한 것처럼 액티비티 상태를 복구할 수 있도록 하면, 애플리케이션이 액티비티 수명 주기에서
+예기치 못한 이벤트가 일어나도 더욱 탄력적으로 복구될 수 있습니다.</p>
+
+<p>이러한 재시작을 처리하는 가장 좋은 방법은 이전 섹션에서 논의한 바와 같이
+{@link
+ android.app.Activity#onSaveInstanceState onSaveInstanceState()}와 {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}(또는 {@link
+android.app.Activity#onCreate onCreate()})를 사용하여 액티비티 상태를 저장하고 복구하는 것입니다.</p>
+
+<p>런타임에 발생하는 구성 변경과 그 처리 방법에 대한 자세한 정보는
+<a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경
+처리하기</a>에 대한 가이드를 읽어보십시오.</p>
+
+
+
+<h3 id="CoordinatingActivities">액티비티 조정하기</h3>
+
+ <p>한 액티비티가 다른 액티비티를 시작하면, 둘 모두 수명 주기 전환을 겪습니다. 첫 번째 액티비티는
+일시중지하고 중단되는 반면(배경에서 계속 보이는 경우에는 중단되지 않습니다만), 다른 액티비티는
+생성되는 것입니다. 이와 같은 액티비티가 디스크 또는 다른 속에 저장된 데이터를 공유하는 경우,
+첫 번째 액티비티는 두 번째 액티비티가 생성되기 전에 완전히 중단되지 않는다는 점을 이해하는 것이 중요합니다.
+그렇다기보다는, 두 번째 액티비티의 시작 과정이 첫 번째 액티비티 중단 과정과 겹쳐 일어납니다.
+</p>
+
+<p>수명 주기 콜백은 분명히 정의된 순서가 있으며 특히 두 개의 액티비티가
+같은 프로세스 안에 있으면서 하나가 다른 하나를 시작하는 경우 순서가 더욱 확실합니다. 다음은 액티비티 A가
+액티비티 B를 시작할 때 발생하는 작업 순서입니다. </p>
+
+<ol>
+<li>액티비티 A의 {@link android.app.Activity#onPause onPause()} 메서드가 실행됩니다.</li>
+
+<li>액티비티 B의 {@link android.app.Activity#onCreate onCreate()}, {@link
+android.app.Activity#onStart onStart()}, {@link android.app.Activity#onResume onResume()}
+메서드가 순차적으로 실행됩니다 (이제 사용자는 액티비티 B에 시선을 집중합니다).</li>
+
+<li>그런 다음, 액티비티 A가 더 이상 화면에 표시되지 않는 경우 이 액티비티의 {@link
+android.app.Activity#onStop onStop()} 메서드가 실행됩니다.</li>
+</ol>
+
+ <p>이처럼 수명 주기 콜백의 순서를 예측할 수 있기 때문에 한 액티비티에서 다른 액티비티로 전환되는
+ 정보를 관리할 수 있습니다. 예를 들어 첫 번째 액티비티가 중단될 때 데이터베이스에
+내용을 작성해서 다음 액티비티가 그 내용을 읽을 수 있도록 하려면, 데이터베이스에는
+{@link android.app.Activity#onPause onPause()} 중에({@link
+android.app.Activity#onStop onStop()} 중이 아니라) 쓰기 작업을 해야 합니다.</p>
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For more information about how Android maintains a history of activities and
+enables user multitasking, continue with the <b><a
+href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back
+Stack</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/ko/guide/components/bound-services.jd b/docs/html-intl/intl/ko/guide/components/bound-services.jd
new file mode 100644
index 000000000000..bf97b260a7da
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/bound-services.jd
@@ -0,0 +1,658 @@
+page.title=바인딩된 서비스
+parent.title=서비스
+parent.link=services.html
+@jd:body
+
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Basics">기본 정보</a></li>
+ <li><a href="#Creating">바인딩된 서비스 생성</a>
+ <ol>
+ <li><a href="#Binder">바인더 클래스 확장</a></li>
+ <li><a href="#Messenger">메신저 사용</a></li>
+ </ol>
+ </li>
+ <li><a href="#Binding">서비스에 바인딩</a></li>
+ <li><a href="#Lifecycle">바인딩된 서비스 수명 주기 관리</a></li>
+</ol>
+
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.app.Service}</li>
+ <li>{@link android.content.ServiceConnection}</li>
+ <li>{@link android.os.IBinder}</li>
+</ol>
+
+<h2>샘플</h2>
+<ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+ RemoteService}</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+ LocalService}</a></li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+ <li><a href="{@docRoot}guide/components/services.html">서비스</a></li>
+</ol>
+</div>
+
+
+<p>바인딩된 서비스란 클라이언트 서버 인터페이스 안의 서버를 말합니다. 바인딩된 서비스를 사용하면 구성 요소(활동 등)를
+서비스에 바인딩되게 하거나, 요청을 보내고 응답을 수신하며 심지어는
+프로세스간 통신(IPC)까지 수행할 수 있게 됩니다. 일반적으로 바인딩된 서비스는 다른 애플리케이션
+구성 요소를 도울 때까지만 살고 배경에서 무한히 실행되지 않습니다.</p>
+
+<p>이 문서는 다른 애플리케이션 구성 요소의
+서비스에 바인딩하는 방법을 포함하여 바인딩된 서비스를 만드는 방법을 보여줍니다. 하지만 일반적인 서비스에 관한 정보도 알아두는 것이 좋습니다.
+서비스에서 알림을 전달하는 방법이나 서비스를 전경에서 실행되도록 설정하는 방법 등 여러 가지
+추가 정보를 알아보려면 <a href="{@docRoot}guide/components/services.html">서비스</a> 문서를 참조하십시오.</p>
+
+
+<h2 id="Basics">기본 정보</h2>
+
+<p>바인딩된 서비스란 일종의 {@link android.app.Service} 클래스 구현으로,
+이를 통해 다른 애플리케이션이 이 서비스에 바인딩하여 상호 작용할 수 있도록 해주는 것입니다. 한 서비스에 대한 바인딩을 제공하려면,
+{@link android.app.Service#onBind onBind()} 콜백 메서드를 구현해야 합니다.
+이 메서드는 클라이언트가 서비스와 상호 작용하는 데 사용하는 프로그래밍 인터페이스를 정의하는 {@link android.os.IBinder} 개체를
+반환합니다.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>시작된 서비스에 바인딩</h3>
+
+<p><a href="{@docRoot}guide/components/services.html">서비스</a>
+문서에서 논의된 바와 같이, 시작되었으면서도 바인딩된 서비스를 만들 수 있습니다. 다시 말해,
+{@link android.content.Context#startService startService()}를 호출하여 서비스를 시작할 수 있으며
+이를 통해 서비스가 무한히 실행되도록 할 수 있으며, {@link
+android.content.Context#bindService bindService()}를 호출하면 클라이언트가 해당 서비스에 바인딩되도록 할 수 있다는 것입니다.
+ <p>서비스를 시작되고 바인딩되도록 허용한 다음 서비스가 시작되면
+시스템은 클라이언트가 모두 바인딩을 해제해도 서비스를 소멸시키지 <em>않습니다</em>. 대신,
+직접 서비스를 확실히 중단시켜야 합니다. 그러려면 {@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()}를 호출하면 됩니다.</p>
+
+<p>보통은 {@link android.app.Service#onBind onBind()}
+<em>또는</em> {@link android.app.Service#onStartCommand onStartCommand()}
+중 한 가지만 구현하지만, 둘 모두 구현해야 할 때도 있습니다. 예를 들어, 음악 플레이어의 경우 서비스를 무한히 실행하면서
+바인딩도 제공하도록 허용하는 것이 유용하다는 결론을 내릴 수 있습니다. 이렇게 하면, 한 액티비티가 서비스로 하여금 음악을 재생하도록
+시작한 다음 사용자가 애플리케이션을 떠나더라도 음악을 계속 재생하도록 할 수 있습니다. 그런 다음, 사용자가 애플리케이션으로
+다시 돌아오면 이 액티비티가 서비스를 바인딩하여 재생 제어권을 다시 획득할 수 있습니다.</p>
+
+<p><a href="#Lifecycle">바인딩된 서비스 수명 주기 관리
+</a> 관련 섹션을 꼭 읽어보십시오. 시작된 서비스에 바인딩을
+추가할 때 서비스 수명 주기에 관한 자세한 정보를 얻을 수 있습니다.</p>
+</div>
+</div>
+
+<p>클라이언트가 서비스에 바인딩하려면 {@link android.content.Context#bindService
+bindService()}를 호출하면 됩니다. 이 때, 반드시 {@link
+android.content.ServiceConnection}의 구현을 제공해야 하며 이것이 서비스와의 연결을 모니터링합니다. {@link
+android.content.Context#bindService bindService()} 메서드는 값 없이 즉시 반환됩니다.
+그러나 Android 시스템이 클라이언트와 서비스 사이의
+연결을 만드는 경우, 시스템은 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()}를 {@link
+android.content.ServiceConnection}에서 호출하여 클라이언트가 서비스와 통신하는 데 사용할 수 있도록 {@link android.os.IBinder}를
+전달하게 됩니다.</p>
+
+<p>여러 클라이언트가 한 번에 서비스에 연결될 수 있습니다. 그러나, 시스템이 서비스의
+{@link android.app.Service#onBind onBind()} 메서드를 호출하여 {@link android.os.IBinder}를 검색하는 경우는 첫 번째 클라이언트가
+바인딩되는 경우뿐입니다. 시스템은 그 후 같은 {@link android.os.IBinder}를 바인딩되는 추가
+클라이언트 모두에 전달하며 이때는 {@link android.app.Service#onBind onBind()}를 다시 호출하지 않습니다.</p>
+
+<p>마지막 클라이언트가 서비스에서 바인딩을 해제하면 시스템은 서비스를 소멸시킵니다(
+{@link android.content.Context#startService startService()}가 서비스를 시작했을 경우 제외).</p>
+
+<p>바인딩된 서비스를 구현할 때 가장 중요한 부분은
+{@link android.app.Service#onBind onBind()} 콜백 메서드가 반환하는 인터페이스를 정의하는 것입니다.
+서비스의 {@link android.os.IBinder} 인터페이스를 정의하는 방법에는 몇 가지가 있고, 다음
+섹션에서는 각 기법에 관해 논의합니다.</p>
+
+
+
+<h2 id="Creating">바인딩된 서비스 생성</h2>
+
+<p>바인딩을 제공하는 서비스를 생성할 때는 클라이언트가 서비스와 상호 작용하는 데 사용할 수 있는 프로그래밍 인터페이스를 제공하는 {@link android.os.IBinder}
+를 제공해야 합니다.
+인터페이스를 정의하는 방법은 세 가지가 있습니다.</p>
+
+<dl>
+ <dt><a href="#Binder">바인더 클래스 확장</a></dt>
+ <dd>서비스가 본인의 애플리케이션 전용이며 클라이언트와 같은 과정으로 실행되는
+경우(이런 경우가 흔함), 인터페이스를 생성할 때 {@link android.os.Binder} 클래스를
+ 확장하고 그 인스턴스를
+{@link android.app.Service#onBind onBind()}에서 반환하는 방식을 사용해야 합니다. 클라이언트가 {@link android.os.Binder}를 받으며,
+이를 사용하여 {@link android.os.Binder} 구현 또는 심지어 {@link android.app.Service}에서
+사용할 수 있는 공개 메서드에 직접 액세스할 수 있습니다.
+ <p>이것은 서비스가 본인의 애플리케이션을 위해 단순히 배경에서 작동하는 요소에 그치는 경우
+선호되는 기법입니다. 인터페이스를 생성할 때 이 방식을 사용하지 않는 유일한 이유는
+서비스를 다른 애플리케이션에서나 별도의 프로세스에 걸쳐 사용하고 있는 경우뿐입니다.</dd>
+
+ <dt><a href="#Messenger">메신저 사용</a></dt>
+ <dd>인터페이스를 여러 프로세스에 걸쳐 적용되도록 해야 하는 경우, 서비스에 대한
+인터페이스를 {@link android.os.Messenger}로 생성할 수 있습니다.
+이 방식을 사용하면 서비스가 여러 가지 유형의 {@link
+android.os.Message} 개체에 응답하는 {@link android.os.Handler}를 정의합니다. 이 {@link android.os.Handler}
+가 {@link android.os.Messenger}의 기초이며, 이를 통해 클라이언트와 함께 {@link android.os.IBinder}
+를 공유할 수 있게 되어 클라이언트가 {@link
+android.os.Message} 개체를 사용해 서비스에 명령을 보낼 수 있게 해줍니다. 이외에도, 클라이언트가 자체적으로 {@link android.os.Messenger}를
+정의하여 서비스가 메시지를 돌려보낼 수 있도록 할 수도 있습니다.
+ <p>이것이 프로세스간 통신(IPC)을 수행하는 가장 간단한 방법입니다. {@link
+android.os.Messenger}가 모든 요청을 단일 스레드에 대기하게 해서, 서비스를 스레드로부터 안전하게
+설계하지 않아도 되기 때문입니다.</p>
+ </dd>
+
+ <dt>AIDL 사용하기</dt>
+ <dd>AIDL(Android Interface Definition Language)은 개체를 운영 체제가 이해할 수 있는
+원시 데이터로 구성 해제한 다음 여러 프로세스에 걸쳐 집결하여 IPC를 수행하기 위해
+필요한 모든 작업을 수행합니다. 이전 기법은 {@link android.os.Messenger}를 사용했는데,
+사실 그 기본 구조가 AIDL을 기반으로 하고 있는 것입니다. 위에서 언급한 바와 같이 {@link android.os.Messenger}는 단일 스레드에 모든 클라이언트 요청
+대기열을 생성하므로 서비스는 한 번에 요청을 하나씩 수신합니다. 그러나,
+서비스가 동시에 여러 요청을 처리하도록 하고 싶은 경우에는 AIDL을 직접 사용해도
+됩니다. 이 경우, 서비스가 다중 스레딩을 할 수 있어야 하며 스레드로부터 안전하게 구축되었어야 합니다.
+ <p>AIDL을 직접 사용하려면
+프로그래밍 인터페이스를 정의하는 {@code .aidl} 파일을 생성해야 합니다. Android SDK 도구는
+이 파일을 사용하여 인터페이스를 구현하고 IPC를 처리하는 추상 클래스를 생성하고,
+그러면 개발자가 직접 이것을 서비스 내에서 확장하면 됩니다.</p>
+ </dd>
+</dl>
+
+ <p class="note"><strong>참고:</strong> 대부분의 애플리케이션의 경우,
+바인딩된 서비스를 생성하기 위해 AIDL를 사용해서는 <strong>안 됩니다</strong>.
+그러려면 다중 스레딩 기능이 필요할 수 있고, 따라서 더 복잡한 구현을 초래할 수 있기 때문입니다. 따라서 AIDL은
+대부분의 애플리케이션에 적합하지 않으므로 이 문서에서는 여러분의 서비스에 이를 이용하는 방법에 대해 다루지 않습니다. AIDL을 직접 사용해야 한다는 확신이 드는 경우,
+<a href="{@docRoot}guide/components/aidl.html">AIDL</a> 문서를 참조하십시오.
+</p>
+
+
+
+
+<h3 id="Binder">바인더 클래스 확장</h3>
+
+<p>서비스를 사용하는 것이 로컬 애플리케이션뿐이고 여러 프로세스에 걸쳐 작동할 필요가 없는 경우,
+나름의 {@link android.os.Binder} 클래스를 구현하여
+클라이언트로 하여금 서비스 내의 공개 메서드에 직접 액세스할 수 있도록 할 수도 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 이것은 클라이언트와 서비스가
+같은 애플리케이션 및 프로세스에 있는 경우에만 통하며, 이 경우가 가장 보편적입니다. 이 방식이 잘 통하는 경우를 예로 들면,
+음악 애플리케이션에서 자체 서비스에 액티비티를 바인딩하여 배경에서 음악을 재생하도록 해야 하는
+경우가 있습니다.</p>
+
+<p>이렇게 설정하는 방법은 다음과 같습니다.</p>
+<ol>
+ <li>서비스에서 다음 중 한 가지에 해당하는 {@link android.os.Binder}의 인스턴스를 생성합니다.
+ <ul>
+ <li>클라이언트가 호출할 수 있는 공개 메서드 포함</li>
+ <li>클라이언트가 호출할 수 있는 공개 메서드가 있는 현재{@link android.app.Service}
+인스턴스를 반환</li>
+ <li>클라이언트가 호출할 수 있는 공개 메서드가 포함된 서비스가 호스팅하는 다른 클래스의 인스턴스를 반환
+</li>
+ </ul>
+ <li>{@link
+android.app.Service#onBind onBind()} 콜백 메서드에서 이 {@link android.os.Binder}의 인스턴스를 반환합니다.</li>
+ <li>클라이언트의 경우, {@link android.os.Binder}를 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()}
+콜백 메서드에서 받아 제공된 메서드를 사용해 서비스를 바인딩하기 위해 호출합니다.</li>
+</ol>
+
+<p class="note"><strong>참고:</strong> 서비스와 클라이언트가 같은 애플리케이션에
+있어야 하는 것은 그래야만 클라이언트가 반환된 개체를 캐스팅하여 해당 API를 적절하게 호출할 수 있기 때문입니다. 또한
+서비스와 클라이언트는 같은 프로세스에 있어야 하기도 합니다. 이 기법에서는
+여러 프로세스에 걸친 집결 작업을 전혀 수행하지 않기 때문입니다.</p>
+
+<p>예컨대, 어떤 서비스가 클라이언트에게 {@link android.os.Binder} 구현을 통해 서비스 내의
+메서드에 액세스할 수 있도록 한다고 합시다.</p>
+
+<pre>
+public class LocalService extends Service {
+ // Binder given to clients
+ private final IBinder mBinder = new LocalBinder();
+ // Random number generator
+ private final Random mGenerator = new Random();
+
+ /**
+ * Class used for the client Binder. Because we know this service always
+ * runs in the same process as its clients, we don't need to deal with IPC.
+ */
+ public class LocalBinder extends Binder {
+ LocalService getService() {
+ // Return this instance of LocalService so clients can call public methods
+ return LocalService.this;
+ }
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /** method for clients */
+ public int getRandomNumber() {
+ return mGenerator.nextInt(100);
+ }
+}
+</pre>
+
+<p>{@code LocalBinder}는 클라이언트에게 {@code LocalService}의 현재 인스턴스를 검색하기 위한 {@code getService()} 메서드
+를 제공합니다. 이렇게 하면 클라이언트가 서비스 내의 공개 메서드를 호출할 수 있습니다.
+ 클라이언트는 예컨대 서비스에서 {@code getRandomNumber()}를 호출할 수 있습니다.</p>
+
+<p>다음은 버튼을 클릭했을 때 {@code LocalService}에 바인딩되며 {@code getRandomNumber()}
+를 호출하는 액티비티를 나타낸 것입니다.</p>
+
+<pre>
+public class BindingActivity extends Activity {
+ LocalService mService;
+ boolean mBound = false;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to LocalService
+ Intent intent = new Intent(this, LocalService.class);
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+
+ /** Called when a button is clicked (the button in the layout file attaches to
+ * this method with the android:onClick attribute) */
+ public void onButtonClick(View v) {
+ if (mBound) {
+ // Call a method from the LocalService.
+ // However, if this call were something that might hang, then this request should
+ // occur in a separate thread to avoid slowing down the activity performance.
+ int num = mService.getRandomNumber();
+ Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /** Defines callbacks for service binding, passed to bindService() */
+ private ServiceConnection mConnection = new ServiceConnection() {
+
+ &#64;Override
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ // We've bound to LocalService, cast the IBinder and get LocalService instance
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ &#64;Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mBound = false;
+ }
+ };
+}
+</pre>
+
+<p>위 예시는 클라이언트가
+{@link android.content.ServiceConnection} 구현과 {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} 콜백을 사용하여 서비스에 바인딩하는 방법을 보여줍니다. 다음
+섹션에서는 서비스에 바인딩하는 이러한 과정에 대해 좀 더 자세한 정보를 제공합니다.</p>
+
+<p class="note"><strong>참고:</strong> 위 예시에서는 서비스에서 분명히 바인딩을 해제하지는 않습니다.
+그러나 모든 클라이언트는 적절한 시점에 바인딩을 해제해야 합니다(액티비티가 일시 중지될 때 등).</p>
+
+<p>더 많은 샘플 코드를 보려면 <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>에서 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+LocalService.java}</a> 클래스와 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code
+LocalServiceActivities.java}</a> 클래스를 참조하십시오.</p>
+
+
+
+
+
+<h3 id="Messenger">메신저 사용</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h4>AIDL과 비교</h4>
+ <p>IPC를 수행해야 할 경우, 인터페이스에 대해 {@link android.os.Messenger}를 사용하는 것이
+AIDL로 구현하는 것보다 간단합니다. 왜냐하면 {@link android.os.Messenger}는
+모든 호출을 서비스에 대기시키지만 순수한 AIDL 인터페이스는
+서비스에 동시에 요청을 전송하여 다중 스레딩을 처리해야 하기 때문입니다.</p>
+ <p>대부분의 애플리이션에서는 서비스가 다중 스레딩을 수행할 필요가 없으므로 {@link
+android.os.Messenger}를 사용하면 호출을 한 번에 하나씩 처리할 수 있습니다. 서비스가
+다중 스레딩되는 것이 중요한 경우, 인터페이스를 정의하는 데 <a href="{@docRoot}guide/components/aidl.html">AIDL</a>을 사용해야 합니다.</p>
+</div>
+</div>
+
+<p>서비스가 원격 프로세스와 통신해야 한다면 서비스에 인터페이스를 제공하는 데
+{@link android.os.Messenger}를 사용하면 됩니다. 이 기법을 사용하면
+AIDL을 쓰지 않고도 프로세스간 통신(IPC)을 수행할 수 있게 해줍니다.</p>
+
+<p>다음은 {@link android.os.Messenger} 사용 방법을 간략하게 요약한 것입니다.</p>
+
+<ul>
+ <li>서비스가 클라이언트로부터 각 호출에 대해 콜백을 받는 {@link android.os.Handler}를
+구현합니다.</li>
+ <li>{@link android.os.Handler}를 사용하여 {@link android.os.Messenger} 개체를 생성합니다
+(이것은 {@link android.os.Handler}에 대한 참조입니다).</li>
+ <li>{@link android.os.Messenger}가 {@link android.os.IBinder}를 생성하여 서비스가
+{@link android.app.Service#onBind onBind()}로부터 클라이언트에게 반환하도록 합니다.</li>
+ <li>클라이언트는 {@link android.os.IBinder}를 사용하여 {@link android.os.Messenger}
+(서비스의 {@link android.os.Handler}를 참조)를 인스턴트화하고, 이를 이용하여
+{@link android.os.Message} 개체를 서비스에 전송합니다.</li>
+ <li>서비스가 각 {@link android.os.Message}를 {@link
+android.os.Handler}로 수신합니다. 구체적으로는 {@link android.os.Handler#handleMessage
+handleMessage()} 메서드를 사용합니다.</li>
+</ul>
+
+
+<p>이렇게 하면, 클라이언트가 서비스에서 호출할 "메서드"가 없습니다. 대신 클라이언트는
+"메시지"({@link android.os.Message} 개체)를 전달하여 서비스가
+{@link android.os.Handler}로 받을 수 있도록 합니다.</p>
+
+<p>다음은 {@link android.os.Messenger} 인터페이스를 사용하는 간단한 예시 서비스입니다.</p>
+
+<pre>
+public class MessengerService extends Service {
+ /** Command to the service to display a message */
+ static final int MSG_SAY_HELLO = 1;
+
+ /**
+ * Handler of incoming messages from clients.
+ */
+ class IncomingHandler extends Handler {
+ &#64;Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SAY_HELLO:
+ Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+ /**
+ * Target we publish for clients to send messages to IncomingHandler.
+ */
+ final Messenger mMessenger = new Messenger(new IncomingHandler());
+
+ /**
+ * When binding to the service, we return an interface to our messenger
+ * for sending messages to the service.
+ */
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
+ return mMessenger.getBinder();
+ }
+}
+</pre>
+
+<p>{@link android.os.Handler}의 {@link android.os.Handler#handleMessage handleMessage()} 메서드에서
+서비스가 수신되는 {@link android.os.Message}를 받고
+{@link android.os.Message#what} 구성원에 기초하여 무엇을 할지 결정한다는 점을 눈여겨 보십시오.</p>
+
+<p>클라이언트는 서비스가 반환한 {@link
+android.os.IBinder}에 기초하여 {@link android.os.Messenger}를 생성하고 {@link
+android.os.Messenger#send send()}로 메시지를 전송하기만 하면 됩니다. 예를 들어, 다음은
+서비스에 바인딩하여 {@code MSG_SAY_HELLO} 메시지를 서비스에 전달하는 간단한 액티비티입니다.</p>
+
+<pre>
+public class ActivityMessenger extends Activity {
+ /** Messenger for communicating with the service. */
+ Messenger mService = null;
+
+ /** Flag indicating whether we have called bind on the service. */
+ boolean mBound;
+
+ /**
+ * Class for interacting with the main interface of the service.
+ */
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // This is called when the connection with the service has been
+ // established, giving us the object we can use to
+ // interact with the service. We are communicating with the
+ // service using a Messenger, so here we get a client-side
+ // representation of that from the raw IBinder object.
+ mService = new Messenger(service);
+ mBound = true;
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ mService = null;
+ mBound = false;
+ }
+ };
+
+ public void sayHello(View v) {
+ if (!mBound) return;
+ // Create and send a message to the service, using a supported 'what' value
+ Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
+ try {
+ mService.send(msg);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to the service
+ bindService(new Intent(this, MessengerService.class), mConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+}
+</pre>
+
+<p>이 예시에는 서비스가 클라이언트에 응답하는 방식이 나타나 있지 않다는 것을 유념하십시오. 서비스가 응답하게 하려면
+ 클라이언트에도 {@link android.os.Messenger}를 생성해야 합니다.
+클라이언트가 {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()} 콜백을 받으면 {@link android.os.Messenger#send send()}메서드의 {@link android.os.Message#replyTo} 매개변수에서 클라이언트의 {@link android.os.Messenger}를 포함하는 {@link android.os.Message}를
+서비스에 전송합니다.
+</p>
+
+<p>양방향 메시지를 제공하는 방법의 예시는 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code
+MessengerService.java}</a>(서비스) 및 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code
+MessengerServiceActivities.java}</a>(클라이언트) 예시를 참조하십시오.</p>
+
+
+
+
+
+<h2 id="Binding">서비스에 바인딩</h2>
+
+<p>애플리케이션 구성 요소(클라이언트)를 서비스에 바인딩하려면
+{@link android.content.Context#bindService bindService()}를 호출하면 됩니다. 그러면 Android
+system이 서비스의 {@link android.app.Service#onBind
+onBind()} 메서드를 호출하고, 이는 서비스와의 상호 작용을 위해 {@link android.os.IBinder}를 반환합니다.</p>
+
+<p>바인딩은 비동기식입니다. {@link android.content.Context#bindService
+bindService()}는 즉시 반환하고 클라이언트에게 {@link android.os.IBinder}를 반환하지 <em>않습니다</em>.
+ {@link android.os.IBinder}를 수신하려면 클라이언트는 {@link
+android.content.ServiceConnection}의 인스턴스를 생성하여 이를 {@link android.content.Context#bindService
+bindService()}에 전달해야 합니다. {@link android.content.ServiceConnection}에는
+{@link android.os.IBinder}를 전달하기 위해 시스템이 호출하는 콜백 메서드가 포함됩니다.</p>
+
+<p class="note"><strong>참고:</strong> 서비스에 바인딩할 수 있는 것은 액티비티, 서비스 및
+콘텐츠 제공자뿐입니다. 브로드캐스트 수신자로부터는 서비스에 바인딩할 수 <strong>없습니다</strong>.</p>
+
+<p>따라서, 클라이언트로부터 서비스에 바인딩하려면 다음과 같이 해야 합니다. </p>
+<ol>
+ <li>{@link android.content.ServiceConnection}을 구현합니다.
+ <p>이 구현으로 두 가지 콜백 메서드를 재정의해야 합니다.</p>
+ <dl>
+ <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt>
+ <dd>시스템이 이것을 호출하여 서비스의
+{@link android.app.Service#onBind onBind()} 메서드가 반환한 {@link android.os.IBinder}를 전달합니다.</dd>
+ <dt>{@link android.content.ServiceConnection#onServiceDisconnected
+onServiceDisconnected()}</dt>
+ <dd>Android 시스템이 이것을 호출하는 경우는 서비스로의 연결이
+예기치 못하게 끊어졌을 때, 즉 서비스가 충돌했거나 중단되었을 때 등입니다.
+클라이언트가 바인딩을 해제한다고 이것이 호출되지는 <em>않습니다</em>.</dd>
+ </dl>
+ </li>
+ <li>{@link
+android.content.Context#bindService bindService()}를 호출하고 {@link
+android.content.ServiceConnection} 구현을 전달합니다. </li>
+ <li>시스템이 {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()} 콜백 메서드를 호출하면, 인터페이스가 정의한 메서드를 사용하여
+서비스에 호출을 시작해도 됩니다.</li>
+ <li>서비스로부터 연결을 해제하려면 {@link
+android.content.Context#unbindService unbindService()}를 호출합니다.
+ <p>클라이언트가 소멸되면 이는 서비스에서 바인딩을 해제하게 되지만,
+서비스와 상호 작용을 마쳤을 때 또는 액티비티가 일시 중지되었을 때에는 항상 바인딩을 해제해야 합니다.
+이렇게 해야 서비스가 사용 중이 아닐 때에는 중지할 수 있습니다
+(바인딩과 바인딩 해제의 적절한 시기는 아래에서 좀 더 논의합니다).</p>
+ </li>
+</ol>
+
+<p>예를 들어, 다음 코드 조각은 위와 같이
+<a href="#Binder">바인더 클래스를 확장해서</a> 생성한 서비스와 클라이언트를 연결합니다. 그러므로 이것이 해야 하는 일은 반환된
+{@link android.os.IBinder}를 {@code LocalService} 클래스에 캐스팅하고 {@code
+LocalService} 인스턴스를 요청하는 것뿐입니다.</p>
+
+<pre>
+LocalService mService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Because we have bound to an explicit
+ // service that is running in our own process, we can
+ // cast its IBinder to a concrete class and directly access it.
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "onServiceDisconnected");
+ mBound = false;
+ }
+};
+</pre>
+
+<p>이 {@link android.content.ServiceConnection}이 있으면 클라이언트는
+이것을 {@link android.content.Context#bindService bindService()}에 전달하여 서비스에 바인딩할 수 있습니다. 예:</p>
+
+<pre>
+Intent intent = new Intent(this, LocalService.class);
+bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+</pre>
+
+<ul>
+ <li>{@link android.content.Context#bindService bindService()}의 첫 번째 매개변수는 바인딩할 서비스를 명시적으로 명명하는
+{@link android.content.Intent}입니다(인텐트는
+암시적일 수 있음).</li>
+<li>두 번째 매개변수는 {@link android.content.ServiceConnection} 개체입니다.</li>
+<li>세 번째 매개변수는 바인딩 옵션을 나타내는 플래그입니다. 서비스를 생성하기 위해 보통은 {@link
+android.content.Context#BIND_AUTO_CREATE}를 사용합니다(이미 살아 있는 상태가 아닌 경우).
+가능한 기타 값은 {@link android.content.Context#BIND_DEBUG_UNBIND}
+ 및 {@link android.content.Context#BIND_NOT_FOREGROUND}, 또는 값이 없는 경우 {@code 0}입니다.</li>
+</ul>
+
+
+<h3>추가 참고 사항</h3>
+
+<p>다음은 서비스에 바인딩하는 데 관한 몇 가지 중요한 참고 사항입니다.</p>
+<ul>
+ <li>항상 {@link android.os.DeadObjectException} 예외를 트래핑해야 합니다.
+이것은 연결이 끊어지면 발생합니다. 원격 메서드에 의해 발생하는 예외는 이것뿐입니다.</li>
+ <li>개체는 여러 프로세스에 걸쳐 감안된 참조입니다. </li>
+ <li>일반적으로, 클라이언트의 수명 주기를
+결합하고 분해하는 순간을 일치시키면서 바인딩과 바인딩 해제를 페어링해야 합니다. 예:
+ <ul>
+ <li>액티비티가 눈에 보이는 동안에만 서비스와 상호 작용해야 한다면
+{@link android.app.Activity#onStart onStart()}에는 바인딩하고 {@link
+android.app.Activity#onStop onStop()}에는 바인딩을 해제해야 합니다.</li>
+ <li>
+배경에서 중단되었을 때도 액티비티가 응답을 받게 하고 싶다면 {@link android.app.Activity#onCreate onCreate()}에는 바인딩하고
+{@link android.app.Activity#onDestroy onDestroy()} 중에는 바인딩을 해제합니다.
+이때, 사용자의 액티비티가 서비스가 실행되는 시간 전체에서(배경에서라도) 서비스를 사용한다는 것을 유념해야 합니다.
+서비스가 다른 프로세스에 있을 경우, 사용자가 프로세스의 가중치를 높이면 시스템이
+이를 중단할 가능성이 높아집니다.</li>
+ </ul>
+ <p class="note"><strong>참고:</strong> 일반적으로는, 액티비티의 {@link android.app.Activity#onResume onResume()}와 {@link
+android.app.Activity#onPause onPause()}에는 바인딩하거나 바인딩을 해제하지 <strong>말아야</strong> 합니다. 이러한 콜백은 모든 수명 주기 전환에서 발생하고
+이런 전환에서 발생하는 처리는
+최소한으로 유지해야 하기 때문입니다. 또한,
+사용자 애플리케이션의 여러 액티비티가 동일한 서비스에 바인딩되었고
+두 액티비티 사이에 전환이 있을 경우, 현재 액티비티의 바인딩이 해제된 후(일시중지 중) 다음 액티비티가 바인딩하기 전(재개 중)에
+서비스가 제거되었다가 다시 생성될 수 있습니다 (수명 주기를 조절하기 위한 이러한 액티비티 전환은
+<a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">액티비티</a>
+문서에 설명되어 있습니다).</p>
+</ul>
+
+<p>더 많은 샘플 코드를 보려면 <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>의 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> 클래스를 참조하십시오.</p>
+
+
+
+
+
+<h2 id="Lifecycle">바인딩된 서비스 수명 주기 관리</h2>
+
+<p>서비스가 모든 클라이언트로부터 바인딩 해제되면, Android 시스템이 이를 소멸시킵니다(다만
+{@link android.app.Service#onStartCommand onStartCommand()}와도 함께 시작된 경우는 예외).
+따라서, 서비스가 순전히 바인딩된 서비스일 경우에는 해당 서비스의 수명 주기를 관리하지 않아도 됩니다.
+클라이언트에 바인딩되었는지를 근거로 Android 시스템이 대신 관리해주기 때문입니다.</p>
+
+<p>그러나 {@link android.app.Service#onStartCommand
+onStartCommand()} 콜백 메서드를 구현하기로 선택하는 경우라면 서비스를 확실히 중지해야 합니다.
+서비스가 현재 <em>시작된 것</em>으로 간주되기 때문입니다. 이런 경우, 서비스는 클라이언트에 바인딩되었는지 여부와 관계없이
+{@link android.app.Service#stopSelf()}와 함께 스스로 중단되거나 다른 구성 요소가{@link
+android.content.Context#stopService stopService()}를 호출할 때까지 실행됩니다.
+</p>
+
+<p>또한, 서비스가 시작되고 바인딩을 허용할 경우 시스템이
+{@link android.app.Service#onUnbind onUnbind()} 메서드를 호출하면
+{@code true}를 선택적으로 반환할 수 있습니다. 다음에 클라이언트가 서비스에 바인딩할 때({@link
+android.app.Service#onBind onBind()}에 대한 호출을 수신하지 않고) {@link android.app.Service#onRebind
+onRebind()}에 대한 호출을 받을지 여부에 따라 결정됩니다. {@link android.app.Service#onRebind
+onRebind()}가 void를 반환하였지만 클라이언트가
+{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} 콜백에서 {@link android.os.IBinder}를 여전히 수신합니다.
+아래 그림 1은 이런 수명 주기의 논리를 나타냅니다.</p>
+
+
+<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 시작되었으며 바인딩도 허용하는 서비스의 수명 주기입니다.
+</p>
+
+
+<p>시작된 서비스의 수명 주기에 관한 자세한 정보는 <a href="{@docRoot}guide/components/services.html#Lifecycle">서비스</a> 문서를 참조하십시오.</p>
+
+
+
+
diff --git a/docs/html-intl/intl/ko/guide/components/fragments.jd b/docs/html-intl/intl/ko/guide/components/fragments.jd
new file mode 100644
index 000000000000..a41250c38d9f
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/fragments.jd
@@ -0,0 +1,812 @@
+page.title=프래그먼트
+parent.title=액티비티
+parent.link=activities.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#Design">디자인 철학</a></li>
+ <li><a href="#Creating">프래그먼트 생성</a>
+ <ol>
+ <li><a href="#UI">사용자 인터페이스 추가하기</a></li>
+ <li><a href="#Adding">액티비티에 프래그먼트 추가</a></li>
+ </ol>
+ </li>
+ <li><a href="#Managing">프래그먼트 관리</a></li>
+ <li><a href="#Transactions">프래그먼트 트랜잭션 수행</a></li>
+ <li><a href="#CommunicatingWithActivity">액티비티와 통신</a>
+ <ol>
+ <li><a href="#EventCallbacks">액티비티로의 이벤트 콜백 생성</a></li>
+ <li><a href="#ActionBar">작업 모음에 항목 추가</a></li>
+ </ol>
+ </li>
+ <li><a href="#Lifecycle">프래그먼트 수명 주기 처리</a>
+ <ol>
+ <li><a href="#CoordinatingWithActivity">액티비티 수명 주기와 조화</a></li>
+ </ol>
+ </li>
+ <li><a href="#Example">예</a></li>
+ </ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.app.Fragment}</li>
+ <li>{@link android.app.FragmentManager}</li>
+ <li>{@link android.app.FragmentTransaction}</li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/fragments/index.html">프래그먼트로 동적 UI 구축하기</a></li>
+ <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">태블릿
+및 핸드셋 지원</a></li>
+ </ol>
+</div>
+</div>
+
+<p>{@link android.app.Fragment}는 동작 또는
+{@link android.app.Activity} 내에서 사용자 인터페이스의 일부를 나타냅니다. 여러 개의 프래그먼트를 하나의 액티비티에
+조합하여 창이 여러 개인 UI를 구축할 수 있으며, 하나의 프래그먼트를 여러 액티비티에서 재사용할 수 있습니다. 프래그먼트는 자체 수명 주기를 가지고, 자체 입력 이벤트를 받으며,
+액티비티 실행 중에 추가 및 제거가 가능한 액티비티의 모듈식 섹션이라고
+생각하면 됩니다(다른 액티비티에
+재사용할 수 있는 "하위 액티비티"와 같은 개념).</p>
+
+<p>프래그먼트는 항상 액티비티 내에 포함되어 있어야 하며 해당 프래그먼트의 수명 주기는
+호스트 액티비티의 수명 주기에 직접적으로 영향을 받습니다. 예를 들어 액티비티가 일시정지되는 경우, 그 안의 모든 프래그먼트도
+일시정지되며 액티비티가 소멸되면 모든 프래그먼트도 마찬가지로 소멸됩니다. 그러나 액티비티가 실행 중인
+동안에는(<em>재개됨</em> <a href="{@docRoot}guide/components/activities.html#Lifecycle">수명 주기 상태</a>에 있을 때를 말합니다)
+각 프래그먼트를 추가 또는 제거하는 등 개별적으로 조작할 수 있습니다. 그와 같은 프래그먼트 트랜잭션을
+수행할 때에는 이를 액티비티가 관리하는 백 스택에도
+추가할 수 있습니다. 각 백 스택 항목이 발생한 프래그먼트 트랜잭션의
+기록이 됩니다. 이 백 스택을 사용하면 사용자가 프래그먼트 트랜잭션을 거꾸로 돌릴 수 있습니다(뒤로 이동).
+이때 <em>뒤로</em> 버튼을 누르면 됩니다.</p>
+
+<p>프래그먼트를 액티비티 레이아웃의 일부로 추가하는 경우, 이는 액티비티의 보기 계층 내부의 {@link
+android.view.ViewGroup} 안에 살며, 해당 프래그먼트가 자신의 보기
+레이아웃을 정의합니다.
+프래그먼트를 액티비티 레이아웃에 삽입하려면 해당 프래그먼트를
+액티비티의 레이아웃 파일에서 {@code &lt;fragment&gt;} 요소로 선언하거나, 애플리케이션 코드에서 이를
+기존의 {@link android.view.ViewGroup}에 추가하면 됩니다. 그러나 프래그먼트가
+액티비티 레이아웃의 일부분이어야만 하는 것은 아닙니다. 나름의 UI가 없는 프래그먼트도 액티비티를 위한
+보이지 않는 작업자로 사용할 수 있습니다.</p>
+
+<p>이 문서에서는 프래그먼트를 사용하도록 애플리케이션을 구축하는 법을
+설명합니다. 그중에는 프래그먼트를 액티비티의 백 스택에 추가했을 때 프래그먼트가 자신의 상태를 유지하는 방법,
+액티비티 및 액티비티 내의 다른 프래그먼트와 이벤트를 공유하는 방법과 액티비티의
+작업 모음에 참가하는 법 등등 여러 가지가 포함됩니다.</p>
+
+
+<h2 id="Design">디자인 철학</h2>
+
+<p>Android가 프래그먼트를 처음 도입한 것은 Android 3.0(API 레벨 11)부터입니다. 기본적으로
+태블릿과 같은 큰 화면에서 보다 역동적이고 유연한 UI 디자인을 지원하는 것이 목적이었습니다. 태블릿의 화면은
+핸드셋 화면보다 훨씬 크기 때문에 UI 구성 요소를 조합하고 상호 교환할 공간이
+더 많습니다. 프래그먼트는 개발자가 보기 계층에 복잡한 변경 내용을 관리하지 않아도
+그러한 디자인을 사용할 수 있도록 해주는 것입니다. 한 액티비티의 레이아웃을 여러 프래그먼트로 나누면
+런타임에 액티비티의 외관을 수정할 수도 있고 그러한 변경 내용을 해당 액티비티가 관리하는
+백 스택에 보존할 수도 있습니다.</p>
+
+<p>예를 들어 뉴스 애플리케이션이라면 하나의 프래그먼트를 사용하여
+왼쪽에 기사 목록을 표시하도록 하고 또 다른 프래그먼트로 오른쪽에 기사 내용을 표시하도록 할 수 있습니다. 두 프래그먼트 모두
+한 액티비티에서 양쪽으로 나란히 나타나며, 각 프래그먼트에 나름의 수명 주기 콜백 메서드가 있고
+각자 사용자 입력 이벤트를 따로 처리하게 됩니다. 따라서, 사용자는 기사를 선택하는 데 한 액티비티를 쓰고
+기사를 읽는 데 또 다른 액티비티를 선택하는 대신에 같은 액티비티 안에서 기사를 선택하고 읽는 과정을
+모두 끝낼 수 있는 것입니다. 이것은 그림 1에 나타낸 태블릿 레이아웃과 같습니다.</p>
+
+<p>프래그먼트를 디자인할 때에는 각 프래그먼트를 모듈식이며 재사용 가능한 액티비티 구성 요소로 만들어야 합니다.
+다시 말해, 각 프래그먼트가 나름의 레이아웃을 따로 정의하고 자기만의 수명 주기 콜백으로 자기 나름의 동작을 정의하기 때문에
+한 프래그먼트를 여러 액티비티에 포함시킬 수 있습니다. 그러므로 재사용을 염두에 두고 디자인하며
+한 프래그먼트를 또 다른 프래그먼트로부터 직접 조작하는 것은 삼가야 합니다. 이것은 특히 모듈식 프래그먼트를 사용하면
+프래그먼트 조합을 여러 가지 화면 크기에 맞춰 변경할 수 있도록 해주기 때문에 중요한 요점입니다. 태블릿과 핸드셋을 모두 지원하는
+애플리케이션을 디자인하는 경우, 사용 가능한 화면 공간을 토대로 사용자 경험을 최적화하도록 프래그먼트를
+여러 레이아웃 구성에 재사용할 수 있습니다. 예를 들어 핸드셋에서의 경우
+프래그먼트를 분리해서 단일 창 UI를 제공하도록 해야할 수 있습니다. 같은 액티비티 안에 하나 이상이 들어가지 않을 수
+있기 때문입니다.</p>
+
+<img src="{@docRoot}images/fundamentals/fragments.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 프래그먼트가 정의한 두 가지 UI 모듈이
+태블릿 디자인에서는 하나의 액티비티로 조합될 수 있는 반면 핸드셋 디자인에서는 분리될 수 있다는 것을
+예시로 나타낸 것입니다.</p>
+
+<p>예를 들어&mdash;뉴스 애플리케이션 예시를 계속 사용하겠습니다&mdash;이 애플리케이션을 태블릿 크기의 기기에서 실행하는 경우,
+애플리케이션 내의 <em>액티비티 A</em> 안에 두 개의 프래그먼트를 포함시킬 수 있습니다. 그러나
+핸드셋 크기의 화면에서라면 두 프래그먼트를 모두 쓸 만큼 공간이 충분치 않습니다.
+따라서 <em>액티비티 A</em>에는 기사 목록에 해당되는 프래그먼트만 포함하고, 사용자가 기사를 하나 선택하면 이것이
+<em>액티비티 B</em>를 시작합니다. 여기에 기사를 읽을 두 번째 프래그먼트가 포함되어 있습니다. 따라서 이 애플리케이션은
+서로 다른 조합으로 프래그먼트를 재사용함으로써 태블릿과 핸드셋을 둘 다 지원하는
+것입니다(그림 1 참조).</p>
+
+<p>여러 가지 화면 구성에 맞게 여러 가지 프래그먼트 조합으로 애플리케이션을 디자인하는 법에 대한 자세한 정보는
+<a href="{@docRoot}guide/practices/tablets-and-handsets.html">태블릿 및 핸드셋 지원</a>에 대한 가이드를 참조하십시오.</p>
+
+
+
+<h2 id="Creating">프래그먼트 생성</h2>
+
+<div class="figure" style="width:327px">
+<img src="{@docRoot}images/fragment_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 2.</strong> 프래그먼트의 수명 주기(
+소속 액티비티가 실행 중일 때).</p>
+</div>
+
+<p>프래그먼트를 생성하려면 {@link android.app.Fragment}의 하위 클래스(또는 이의 기존
+하위 클래스)를 생성해야 합니다. {@link android.app.Fragment} 클래스에는
+{@link android.app.Activity}와 아주 유사해 보이는 코드가 있습니다. 여기에는 액티비티와 비슷한 콜백 메서드가 들어 있습니다.
+예를 들어 {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()},
+{@link android.app.Fragment#onPause onPause()} 및 {@link android.app.Fragment#onStop onStop()} 등입니다. 사실,
+기존 Android 애플리케이션을 변환하여 프래그먼트를 사용하도록 하려면 그저
+액티비티의 콜백 메서드에서 프래그먼트에 해당되는 콜백 메서드로 코드를 옮기기만 하면
+될 수도 있습니다.</p>
+
+<p>보통은 최소한 다음과 같은 수명 주기 메서드를 구현해야 합니다.</p>
+
+<dl>
+ <dt>{@link android.app.Fragment#onCreate onCreate()}</dt>
+ <dd>시스템은 프래그먼트를 생성할 때 이것을 호출합니다. 구현 내에서 프래그먼트의 기본 구성 요소 중
+프래그먼트가 일시정지되거나 중단되었다가 재개되었을 때 유지하고자 하는 것을
+초기화해야 합니다.</dd>
+ <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
+ <dd>시스템은 프래그먼트가 자신의 사용자 인터페이스를 처음으로 그릴 시간이 되면
+이것을 호출합니다. 프래그먼트에 맞는 UI를 그리려면 메서드에서 {@link android.view.View}를 반환해야 합니다.
+이 메서드는 프래그먼트 레이아웃의 루트입니다. 프래그먼트가 UI를 제공하지 않는 경우 null을 반환하면
+됩니다.</dd>
+ <dt>{@link android.app.Activity#onPause onPause()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 사용자가 프래그먼트를 떠난다는
+첫 번째 신호입니다(다만 이것이 항상 프래그먼트가 소멸 중이라는 뜻은 아닙니다). 현재 사용자 세션을 넘어서
+지속되어야 하는 변경 사항을 커밋하려면 보통 이곳에서 해아 합니다(사용자가
+돌아오지 않을 수 있기 때문입니다).</dd>
+</dl>
+
+<p>대부분의 애플리케이션은 각각의 프래그먼트에 이와 같은 메서드를 최소한 세 개씩
+구현해야 하지만, 프래그먼트 수명 주기의 여러 단계를 처리하려면 사용해야 하는 다른 콜백 메서드도
+많이 있습니다. 모든 수명 주기 콜백 메서드는 나중에
+<a href="#Lifecycle">프래그먼트 수명 주기 처리</a> 섹션에서 더욱 상세히 논의할 것입니다.</p>
+
+
+<p>이외에도, 기본적인 {@link
+android.app.Fragment} 클래스 대신 확장하고자 하는 하위 클래스도 몇 개 있을 수 있습니다.</p>
+
+<dl>
+ <dt>{@link android.app.DialogFragment}</dt>
+ <dd>부동 대화 창을 표시합니다. 이 클래스를 사용하여 대화를 생성하면
+{@link android.app.Activity} 클래스의 대화 도우미 메서드를 사용하는 것의
+좋은 대안책이 됩니다. 이렇게 하면 프래그먼트 대화를 액티비티가 관리하는 프래그먼트의 백 스택에 통합시킬 수 있어,
+사용자가 무시된 프래그먼트를 반환할 수 있도록 해주기 때문입니다.</dd>
+
+ <dt>{@link android.app.ListFragment}</dt>
+ <dd>어댑터가 관리하는 항목의 목록(예: {@link
+android.widget.SimpleCursorAdapter})을 표시하며, {@link android.app.ListActivity}와 비슷합니다.
+이것은 목록 보기를 관리하는 데 쓰는 몇 가지 메서드를 제공합니다. 예를 들어 {@link
+android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} 콜백을
+제공하여 클릭 이벤트를 처리하는 것 등입니다.</dd>
+
+ <dt>{@link android.preference.PreferenceFragment}</dt>
+ <dd>{@link android.preference.Preference} 객체의 계층을 목록으로 표시하며,
+{@link android.preference.PreferenceActivity}와 비슷합니다. 이것은
+애플리케이션에 대한 "설정" 액티비티를 생성할 때 유용합니다.</dd>
+</dl>
+
+
+<h3 id="UI">사용자 인터페이스 추가하기</h3>
+
+<p>프래그먼트는 일반적으로 액티비티에 속한 사용자 인터페이스의 일부분으로 사용되며
+자기 나름의 레이아웃으로 액티비티에 참가합니다.</p>
+
+<p>프래그먼트에 대해 레이아웃을 제공하려면 반드시 {@link
+android.app.Fragment#onCreateView onCreateView()} 콜백 메서드를 구현해야 합니다.
+이것은 프래그먼트가 자신의 레이아웃을 그릴 때가 되면 Android 시스템이 호출하는 것입니다. 이 메서드의 구현은 반드시
+{@link android.view.View}를 반환해야 합니다. 이것은 프래그먼트 레이아웃의 루트입니다.</p>
+
+<p class="note"><strong>참고:</strong> 프래그먼트가 {@link
+android.app.ListFragment}의 하위 클래스인 경우, 기본 구현이
+{@link android.app.Fragment#onCreateView onCreateView()}로부터 {@link android.widget.ListView}를 반환하므로 이를 구현하지 않아도 됩니다.</p>
+
+<p>{@link
+android.app.Fragment#onCreateView onCreateView()}로부터 레이아웃을 반환하려면 이를 XML에서 정의된 <a href="{@docRoot}guide/topics/resources/layout-resource.html">레이아웃 리소스</a>로부터 팽창시키면 됩니다. 이를 돕기 위해
+{@link android.app.Fragment#onCreateView onCreateView()}가
+{@link android.view.LayoutInflater} 객체를 제공합니다.</p>
+
+<p>예를 들어 다음은 {@link android.app.Fragment}의 하위 클래스입니다. 이것이
+{@code example_fragment.xml} 파일로부터 레이아웃을 로딩합니다.</p>
+
+<pre>
+public static class ExampleFragment extends Fragment {
+ &#64;Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.example_fragment, container, false);
+ }
+}
+</pre>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>레이아웃 생성</h3>
+ <p>위의 샘플에서 {@code R.layout.example_fragment}는
+애플리케이션 리소스에 저장된 {@code example_fragment.xml}이라는 레이아웃 리소스에 대한 참조입니다. 레이아웃을
+XML로 생성하는 방법에 대한 정보는 <a href="{@docRoot}guide/topics/ui/index.html">사용자 인터페이스</a>
+ 문서를 참조하십시오.</p>
+</div>
+</div>
+
+<p>{@link android.app.Fragment#onCreateView
+onCreateView()}로 전달된 {@code container} 매개변수가 상위 {@link android.view.ViewGroup}이며(액티비티의 레이아웃으로부터),
+이 안에 프래그먼트 레이아웃이 삽입됩니다.
+ {@code savedInstanceState} 매개변수는 일종의 {@link android.os.Bundle}로,
+이것은 프래그먼트가 재개되는 중인 경우 프래그먼트의 이전 인스턴스에 대한 데이터를
+제공합니다(상태를 복원하는 것은 <a href="#Lifecycle">프래그먼트 수명 주기
+처리</a>에서 좀 더 논의합니다).</p>
+
+<p>{@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} 메서드는
+다음과 같은 세 개의 인수를 취합니다.</p>
+<ul>
+ <li>팽창시키고자 하는 레이아웃의 리소스 ID.</li>
+ <li>팽창된 레이아웃의 상위가 될 {@link android.view.ViewGroup}. {@code
+container}를 전달해야 시스템이 레이아웃 매개변수를 팽창된 레이아웃의 루트 보기에 실행 중인 상위 보기에서 지정한 것과 같이
+적용할 수 있으므로 이는 중요한 부분입니다.</li>
+ <li>팽창된 레이아웃이 팽창 중에 {@link
+android.view.ViewGroup}(두 번째 매개변수)에 첨부되어야 하는지를 나타내는 부울 값 (이 경우,
+이것은 거짓입니다. 시스템이 이미 팽창된 레이아웃을 {@code
+container} 안에 삽입하고 있기 때문입니다. 참을 전달하면 최종 레이아웃에 중복된 보기 그룹을 생성하게 됩니다).</li>
+</ul>
+
+<p>이제 레이아웃을 제공하는 프래그먼트 생성하는 법을 알게 되셨습니다. 다음은 프래그먼트를
+액티비티에 추가해야 합니다.</p>
+
+
+
+<h3 id="Adding">액티비티에 프래그먼트 추가</h3>
+
+<p>프래그먼트는 보통 UI의 일부분으로 호스트 액티비티에 참가합니다. 이는 해당 액티비티의
+전반적인 보기 계층의 일부분으로 포함되게 됩니다. 프래그먼트를 액티비티 레이아웃에 추가하는 데에는 두 가지 방법이
+있습니다.</p>
+
+<ul>
+ <li><b>프래그먼트를 액티비티의 레이아웃 파일 안에서 선언합니다.</b>
+<p>이 경우, 프래그먼트에 대한 레이아웃 속성을 마치
+보기인 것처럼 나타낼 수 있습니다. 예를 들어 다음은 프래그먼트가 두 개 있는
+한 액티비티에 대한 레이아웃 파일을 나타낸 것입니다.</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"&gt;
+ &lt;fragment android:name="com.example.news.ArticleListFragment"
+ android:id="@+id/list"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" /&gt;
+ &lt;fragment android:name="com.example.news.ArticleReaderFragment"
+ android:id="@+id/viewer"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" /&gt;
+&lt;/LinearLayout&gt;
+</pre>
+ <p>{@code &lt;fragment&gt;} 안의 {@code android:name} 속성이 레이아웃 안에서 인스턴트화할 {@link
+android.app.Fragment} 클래스를 나타냅니다.</p>
+
+<p>시스템은 이 액티비티 레이아웃을 생성할 때 레이아웃에서 지정된 각 프래그먼트를 인스턴트화하며 각각에 대해
+{@link android.app.Fragment#onCreateView onCreateView()} 메서드를
+호출하여 각 프래그먼트의 레이아웃을 검색합니다. 시스템은 프래그먼트가 반환한 {@link android.view.View}를
+{@code &lt;fragment&gt;} 요소 자리에 곧바로 삽입합니다.</p>
+
+<div class="note">
+ <p><strong>참고:</strong> 각 프래그먼트에는 액티비티가 재시작되는 경우
+프래그먼트를 복구하기 위해 시스템이 사용할 수 있는 고유한 식별자가 필요합니다(그리고, 개발자는 이것을 사용하여 프래그먼트를 캡처해
+이를 제거하는 등 여러 가지 트랜잭션을 수행할 수 있습니다). 프래그먼트에 ID를 제공하는 데에는
+다음과 같은 세 가지 방법이 있습니다.</p>
+ <ul>
+ <li>고유한 ID와 함께 {@code android:id} 속성을 제공합니다.</li>
+ <li>고유한 문자열과 함께 {@code android:tag} 속성을 제공합니다.</li>
+ <li>위의 두 가지 중 어느 것도 제공하지 않으면, 시스템은 컨테이너 보기의 ID를
+사용합니다.</li>
+ </ul>
+</div>
+ </li>
+
+ <li><b>또는, 프로그래밍 방식으로 프래그먼트를 기존의 {@link android.view.ViewGroup}에 추가합니다.</b>
+<p>액티비티가 실행 중인 동안에는 언제든 액티비티 레이아웃에 프래그먼트를 추가할 수 있습니다. 그저 프래그먼트를 배치할
+{@link
+android.view.ViewGroup}를 지정하기만 하면 됩니다.</p>
+ <p>액티비티 내에서 프래그먼트 트랜잭션을 수행하려면(프래그먼트 추가, 제거 또는
+교체 등), {@link android.app.FragmentTransaction}에서 가져온 API를 사용해야 합니다.
+{@link android.app.FragmentTransaction}의 인스턴스를 {@link android.app.Activity}에서 가져오는 방법은 다음과 같습니다.</p>
+
+<pre>
+FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}
+FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
+</pre>
+
+<p>그런 다음 {@link
+android.app.FragmentTransaction#add(int,Fragment) add()} 메서드를 사용하여 프래그먼트를 추가하고, 추가할 프래그먼트와 이를 삽입할
+보기를 지정하면 됩니다. 예:</p>
+
+<pre>
+ExampleFragment fragment = new ExampleFragment();
+fragmentTransaction.add(R.id.fragment_container, fragment);
+fragmentTransaction.commit();
+</pre>
+
+ <p>{@link android.app.FragmentTransaction#add(int,Fragment) add()}에
+전달되는 첫 인수가 {@link android.view.ViewGroup}입니다.
+여기에 프래그먼트가 리소스 ID가 지정한 바와 같이 배치되어야 하며, 두 번째 매개변수는 추가할 프래그먼트입니다.</p>
+ <p>
+{@link android.app.FragmentTransaction}을 변경하고 나면, 반드시
+{@link android.app.FragmentTransaction#commit}을 호출해야 변경 내용이 적용됩니다.</p>
+ </li>
+</ul>
+
+
+<h4 id="AddingWithoutUI">UI 없이 프래그먼트 추가</h4>
+
+<p>위의 예시에서는 UI를 제공하기 위해 프래그먼트를 액티비티에 추가하는 방법을 보여드렸습니다. 하지만
+추가로 UI를 제시하지 않고 액티비티에 대한 배경 동작을 제공하는 데에도 프래그먼트를 사용할 수
+있습니다.</p>
+
+<p>UI 없이 프래그먼트를 추가하려면 액티비티로부터 가져온 프래그먼트를 {@link
+android.app.FragmentTransaction#add(Fragment,String)}을 사용하여 추가합니다(이때, 프래그먼트에 대해
+보기 ID보다는 고유한 문자열 "태그"를 제공합니다). 이렇게 하면 프래그먼트가 추가되지만,
+이것은 액티비티 레이아웃 안에 있는 보기와 연관되어 있지 않기 때문에 {@link
+android.app.Fragment#onCreateView onCreateView()}로의 호출은 받지 않습니다. 따라서 그 메서드는 구현하지 않아도 됩니다.</p>
+
+<p>프래그먼트에 대해 문자열 태그를 제공하는 것은 엄밀히 말해 비 UI 프래그먼트에만 해당되는 것은 아닙니다. UI가 있는
+프래그먼트에도 문자열 태그를 제공할 수 있습니다. 하지만 프래그먼트에
+UI가 없는 경우라면 이를 식별할 방법은 문자열 태그뿐입니다. 액티비티에서 나중에
+프래그먼트를 가져오고자 하는 경우, {@link android.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}를 사용해야 합니다.</p>
+
+<p>예를 들어 어떤 액티비티에서 UI 없이 프래그먼트를 배경 작업자로 사용한다고 가정해봅시다. 이것의 예로 {@code
+FragmentRetainInstance.java} 샘플을 들 수 있으며
+이는 SDK 샘플에 포함되어 있고(Android SDK Manager를 통해 이용 가능), 시스템에는
+<code>&lt;sdk_root&gt;/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code>로 찾을 수 있습니다.</p>
+
+
+
+<h2 id="Managing">프래그먼트 관리</h2>
+
+<p>액티비티 내의 프래그먼트를 관리하려면 {@link android.app.FragmentManager}를 사용해야 합니다. 이것을
+가져오려면 액티비티에서 {@link android.app.Activity#getFragmentManager()}를 호출하십시오.</p>
+
+<p>{@link android.app.FragmentManager}를 가지고 할 수 있는 여러 가지 일 중에 예를 들면 다음과 같습니다.</p>
+
+<ul>
+ <li>액티비티 내에 존재하는 프래그먼트를 {@link
+android.app.FragmentManager#findFragmentById findFragmentById()}로 가져오기(액티비티 레이아웃 내에서
+UI를 제공하는 프래그먼트의 경우) 또는 {@link android.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}로 가져오기(UI를 제공하거나 하지 않는 프래그먼트의 경우).</li>
+ <li>백 스택에서 프래그먼트를 {@link
+android.app.FragmentManager#popBackStack()}을 사용하여 튀어나오게 하기(사용자가 내린 <em>뒤로</em> 명령을 시뮬레이트함).</li>
+ <li>백 스택에 변경 내용이 있는지 알아보기 위해 {@link
+android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()}로 수신기 등록하기.</li>
+</ul>
+
+<p>이와 같은 메서드와 그 외 다른 메서드에 대한 자세한 정보는 {@link
+android.app.FragmentManager} 클래스 관련 문서를 참조하십시오.</p>
+
+<p>이전 섹션에서 설명한 바와 같이 {@link android.app.FragmentManager}를
+사용해서도 {@link android.app.FragmentTransaction}
+을 열 수 있습니다. 이렇게 하면 프래그먼트 추가 및 제거 등 트랜잭션을 수행할 수 있게 해줍니다.</p>
+
+
+<h2 id="Transactions">프래그먼트 트랜잭션 수행</h2>
+
+<p>액티비티에서 프래그먼트를 사용하는 경우 특히 유용한 점은 사용자 상호 작용에 응답하여 추가,
+제거, 교체 및 다른 작업을 수행할 수 있다는 것입니다. 액티비티에 적용한
+변경 내용의 집합을 하나의 트랜잭션이라 칭합니다. 이것을 수행하려면 {@link
+android.app.FragmentTransaction} 내의 API를 사용하면 됩니다. 해당 액티비티가 관리하는 백 스택에 행해진 각 트랜잭션을
+저장할 수도 있습니다. 이렇게 하면 사용자가 프래그먼트 변경 내역을 거쳐 뒤로 탐색할 수 있습니다(액티비티를 통과해
+뒤로 탐색하는 것과 비슷합니다).</p>
+
+<p>{@link android.app.FragmentTransaction}의 인스턴스를 {@link
+android.app.FragmentManager}로부터 가져오는 방법은 다음과 같습니다.</p>
+
+<pre>
+FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()};
+FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
+</pre>
+
+<p>각 트랜잭션은 동시에 수행하고자 하는 여러 변경을 집합적으로 일컫는 말입니다. 주어진
+트랜잭션에 대해 수행하고자 하는 모든 변경 사항을 설정하려면 {@link
+android.app.FragmentTransaction#add add()}, {@link android.app.FragmentTransaction#remove remove()},
+및 {@link android.app.FragmentTransaction#replace replace()}와 같은 메서드를 사용하면 됩니다. 그런 다음,
+트랜잭션을 액티비티에 적용하려면 반드시 {@link android.app.FragmentTransaction#commit()}을 호출해야 합니다.</p>
+</dl>
+
+<p>하지만 {@link
+android.app.FragmentTransaction#commit()}을 호출하기 전에 먼저 호출해야 할 것이 있습니다. 바로 {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}입니다.
+이렇게 해야 트랜잭션을 프래그먼트 트랜잭션의 백 스택에 추가할 수 있습니다. 이 백 스택을 액티비티가 관리하며,
+이를 통해 사용자가 이전 프래그먼트 상태로 되돌아갈 수 있습니다. 이때 <em>뒤로</em> 버튼을 누르면 됩니다.</p>
+
+<p>예를 들어 다음은 한 프래그먼트를 다른 것으로 교체하고 이전 상태를 백 스택에 보존하는 법을
+나타낸 것입니다.</p>
+
+<pre>
+// Create new fragment and transaction
+Fragment newFragment = new ExampleFragment();
+FragmentTransaction transaction = getFragmentManager().beginTransaction();
+
+// Replace whatever is in the fragment_container view with this fragment,
+// and add the transaction to the back stack
+transaction.replace(R.id.fragment_container, newFragment);
+transaction.addToBackStack(null);
+
+// Commit the transaction
+transaction.commit();
+</pre>
+
+<p>이 예시에서 {@code newFragment}가 현재 레이아웃 컨테이너에 있는
+프래그먼트(있는 경우)를 교체합니다. 이는 {@code R.id.fragment_container} ID로 식별할 수 있습니다. {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}를 호출하면 교체 트랜잭션이
+백 스택에 저장되고, 따라서 사용자가 트랜잭션을 거꾸로 수행하여
+이전 프래그먼트를 도로 가져올 수 있습니다. <em>뒤로</em> 버튼을 사용하면 됩니다.</p>
+
+<p>트랜잭션에 여러 개의 변경을 추가하고(예를 들어 또 다른 {@link
+android.app.FragmentTransaction#add add()} 또는 {@link android.app.FragmentTransaction#remove
+remove()}) {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}을 호출하면, {@link android.app.FragmentTransaction#commit commit()}을 호출하기 전에 적용된 모든 변경 내용이
+백 스택에 하나의 트랜잭션으로 추가되며, <em>뒤로</em> 버튼을 누르면
+모두 한꺼번에 역행하게 됩니다.</p>
+
+<p>{@link android.app.FragmentTransaction}에 변경 내용을 추가하는 순서는 중요하지 않습니다.
+다만 다음과 같은 예외가 있습니다.</p>
+<ul>
+ <li>{@link android.app.FragmentTransaction#commit()}을 마지막으로 호출해야만 합니다.</li>
+ <li>같은 컨테이너에 여러 개의 프래그먼트를 추가하는 경우, 이를 추가하는 순서가 이들이
+보기 계층에 나타나는 순서를 결정 짓습니다.</li>
+</ul>
+
+<p>프래그먼트를 제거하는 트랜잭션을 수행하면서 {@link android.app.FragmentTransaction#addToBackStack(String)
+addToBackStack()}을 호출하지 않는 경우,
+해당 프래그먼트는 트랜잭션이 적용되면 소멸되고 사용자가 이를 되짚어 탐색할 수 없게 됩니다. 반면에
+프래그먼트를 제거하면서 {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()}을 호출하면,
+해당 프래그먼트는 <em>중단</em>되고 사용자가 뒤로 탐색하면
+재개됩니다.</p>
+
+<p class="note"><strong>팁:</strong> 각 프래그먼트 트랜잭션에 대해 전환 애니메이션을 적용하려면
+커밋하기 전에 {@link android.app.FragmentTransaction#setTransition setTransition()}을
+호출하면 됩니다.</p>
+
+<p>{@link android.app.FragmentTransaction#commit()}을 호출해도 그 즉시 트랜잭션을 수행하지는
+않습니다. 그보다는, 액티비티의 UI 스레드("주요" 스레드)를 스레드가 할 수 있는 한 빨리
+이 트랜잭션을 수행하도록 일정을 예약하는 것에 가깝습니다. 하지만 필요한 경우 UI 스레드로부터 {@link
+android.app.FragmentManager#executePendingTransactions()}를 호출하면
+{@link android.app.FragmentTransaction#commit()}이 제출한 트랜잭션을 즉시 실행할 수 있습니다. 트랜잭션이
+다른 스레드의 작업에 대한 종속성이 아니라면 굳이 이렇게 해야만 하는 것은 아닙니다.</p>
+
+<p class="caution"><strong>주의:</strong> 트랜잭션을 적용할 때 {@link
+android.app.FragmentTransaction#commit commit()}을 사용해도 되는 것은 액티비티가 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">그 상태를
+저장</a>하기 전뿐입니다(사용자가 액티비티를 떠날 때). 그 시점 이후에 적용하려고 하면 예외가
+발생합니다. 이것은 액티비티를 복원해야 하는 경우 적용 이후의 상태가 손실될 수
+있기 때문입니다. 적용이 손실되어도 괜찮은 상황이라면, {@link
+android.app.FragmentTransaction#commitAllowingStateLoss()}를 사용하십시오.</p>
+
+
+
+
+<h2 id="CommunicatingWithActivity">액티비티와 통신</h2>
+
+<p>{@link android.app.Fragment}는
+{@link android.app.Activity}로부터 독립적인 객체로 구현되었고 여러 개의 액티비티 안에서 사용할 수 있는 것이 사실이지만,
+프래그먼트의 주어진 인스턴스는 그것을 포함하고 있는 액티비티에 직접적으로 연결되어 있습니다.</p>
+
+<p>구체적으로 말하면, 이 프래그먼트는 {@link
+android.app.Fragment#getActivity()}를 사용하여 {@link android.app.Activity} 인스턴스에 액세스하여
+액티비티 레이아웃에서 보기를 찾는 것과 같은 작업을 손쉽게 수행할 수 있습니다.</p>
+
+<pre>
+View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list);
+</pre>
+
+<p>이와 마찬가지로, 액티비티도 프래그먼트 안의 메서드를 호출할 수 있습니다. 그러려면 {@link android.app.FragmentManager}로부터의
+{@link android.app.Fragment}에 대한 참조를 가져와야 하며, 이때 {@link
+android.app.FragmentManager#findFragmentById findFragmentById()} 또는 {@link
+android.app.FragmentManager#findFragmentByTag findFragmentByTag()}를 사용합니다. 예:</p>
+
+<pre>
+ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
+</pre>
+
+
+<h3 id="EventCallbacks">액티비티로의 이벤트 콜백 생성</h3>
+
+<p>어떤 경우에는 프래그먼트로 하여금 액티비티와 이벤트를 공유하게 해야 할 수 있습니다. 이렇게 하기 위한
+한 가지 좋은 방법은 프래그먼트 내부의 콜백 인터페이스를 정의한 다음 해당 호스트 액티비티가 이를 구현하도록
+하는 것입니다. 액티비티가 인터페이스를 통해 콜백을 수신하면, 필요에 따라 그 정보를 레이아웃 내의
+다른 프래그먼트와 공유할 수 있습니다.</p>
+
+<p>예를 들어 어떤 뉴스 애플리케이션에서 액티비티 하나에 프래그먼트가 두 개 있습니다.
+ 하나는 기사 목록을 표시(프래그먼트 A)하고 다른 하나는 기사 하나를 표시(프래그먼트 B)하는 경우 목록 항목이 선택되면
+프래그먼트 A가 액티비티에 알려야 프래그먼트 B에 해당 기사를 표시하라고 알릴 수 있습니다. 이 경우,
+{@code OnArticleSelectedListener} 인터페이스는 프래그먼트 A 내부에 선언됩니다.</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ ...
+ // Container Activity must implement this interface
+ public interface OnArticleSelectedListener {
+ public void onArticleSelected(Uri articleUri);
+ }
+ ...
+}
+</pre>
+
+<p>그러면 프래그먼트를 호스팅하는 액티비티가 {@code OnArticleSelectedListener}
+ 인터페이스를
+구현하고 {@code onArticleSelected()}를 재정의하여 프래그먼트 A로부터 일어난 이벤트를
+프래그먼트 B에 알립니다. 호스트 액티비티가 이 인터페이스를 구현하도록
+확실히 하려면 프래그먼트 A의 {@link
+android.app.Fragment#onAttach onAttach()} 콜백 메서드(프래그먼트를 액티비티에 추가할 때 시스템이 호출하는 것)가 {@code OnArticleSelectedListener}의 인스턴스를 인스턴트화해야 합니다. 이때 {@link android.app.Fragment#onAttach
+onAttach()} 안으로 전달된 {@link android.app.Activity}를
+캐스팅하는 방법을 씁니다.</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ OnArticleSelectedListener mListener;
+ ...
+ &#64;Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mListener = (OnArticleSelectedListener) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
+ }
+ }
+ ...
+}
+</pre>
+
+<p>액티비티가 인터페이스를 구현하지 않은 경우, 프래그먼트가
+{@link java.lang.ClassCastException}을 발생시킵니다.
+성공 시, {@code mListener} 구성원이 액티비티의
+{@code OnArticleSelectedListener} 구현에 대한 참조를 보유하므로, 프래그먼트 A가 액티비티와 이벤트를 공유할 수 있습니다.
+이때 {@code OnArticleSelectedListener} 인터페이스가 정의한 메서드를 호출하는 방법을 씁니다. 예를 들어 프래그먼트 A가
+{@link android.app.ListFragment}의 확장인 경우,
+사용자가 목록 항목을 클릭할 때마다 시스템이 프래그먼트 안의 {@link android.app.ListFragment#onListItemClick
+onListItemClick()}을 호출하고, 그러면 이것이 {@code onArticleSelected()}를 호출하여
+해당 이벤트를 액티비티와 공유하는 것입니다.</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ OnArticleSelectedListener mListener;
+ ...
+ &#64;Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ // Append the clicked item's row ID with the content provider Uri
+ Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id);
+ // Send the event and Uri to the host activity
+ mListener.onArticleSelected(noteUri);
+ }
+ ...
+}
+</pre>
+
+<p>{@link
+android.app.ListFragment#onListItemClick onListItemClick()}에 전달된 {@code id} 매개변수가 클릭한 항목의 행 ID이며,
+액티비티(또는 다른 프래그먼트)가 이것을 사용해 애플리케이션의 {@link
+android.content.ContentProvider}에서 기사를 가져옵니다.</p>
+
+<p><!--To see a complete implementation of this kind of callback interface, see the <a
+href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->콘텐츠 제공자 사용법에 대한 자세한 정보는
+<a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a> 문서에서 이용하실 수 있습니다.</p>
+
+
+
+<h3 id="ActionBar">작업 모음에 항목 추가</h3>
+
+<p>프래그먼트는 액티비티의 <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">옵션 메뉴</a>에(결과적으로 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>에도) 메뉴 항목으로 참가할 수 있습니다. 이때
+{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}를 구현하는 방법을 씁니다. 이 메서드가
+호출을 수신하도록 하려면, {@link
+android.app.Fragment#onCreate(Bundle) onCreate()} 중에 {@link
+android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()}를 호출하여 프래그먼트가
+옵션 메뉴에 항목을 추가하고자 한다는 것을 나타내야 합니다(그렇지 않으면 해당 프래그먼트가
+{@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}로의 호출을 받지 못하게 됩니다).</p>
+
+<p>그런 다음 프래그먼트로부터 옵션 메뉴에 추가하는 모든 항목은 기존의 메뉴 항목에
+추가됩니다. 해당 프래그먼트는 메뉴 항목을 선택하면 {@link
+android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}로의 콜백도
+수신하게 됩니다.</p>
+
+<p>또한 프래그먼트 레이아웃에 보기를 등록하여 컨텍스트 메뉴를 제공하도록 할 수도 있습니다. 이때 {@link
+android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}를 호출하면 됩니다. 사용자가 컨텍스트 메뉴를 열면,
+해당 프래그먼트가 {@link
+android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo)
+onCreateContextMenu()}로의 호출을 받습니다. 사용자가 항목을 하나 선택하면, 해당 프래그먼트는 {@link
+android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}로의 호출을 받습니다.</p>
+
+<p class="note"><strong>참고:</strong> 프래그먼트는 추가한 각 메뉴 항목에 대해 '항목 선택됨' 콜백을
+하나씩 받게 되지만, 사용자가 메뉴 항목을 선택할 때 그에 상응하는 콜백을 가장 처음 받는 것은
+액티비티입니다. 액티비티가 구현한 '항목 선택됨' 콜백이 선택된 항목을 다루지 않는 경우,
+해당 이벤트는 프래그먼트의 콜백으로 전달됩니다. 이것은
+옵션 메뉴와 컨텍스트 메뉴에 모두 참입니다.</p>
+
+<p>메뉴에 대한 더 자세한 정보는 <a href="{@docRoot}guide/topics/ui/menus.html">메뉴</a> 및 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a> 개발자 가이드를 참조하십시오.</p>
+
+
+
+
+<h2 id="Lifecycle">프래그먼트 수명 주기 처리</h2>
+
+<div class="figure" style="width:350px">
+<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 3.</strong> 액티비티 수명 주기가 프래그먼트 수명 주기에 미치는
+영향입니다.</p>
+</div>
+
+<p>프래그먼트의 수명 주기를 관리하는 것은 액티비티의 수명 주기를 관리하는 것과 매우 비슷합니다. 액티비티와 마찬가지로
+프래그먼트는 세 가지 상태로 존재할 수 있습니다.</p>
+
+<dl>
+ <dt><i>재개됨</i></dt>
+ <dd>프래그먼트가 실행 중인 액티비티에 표시됩니다.</dd>
+
+ <dt><i>일시정지됨</i></dt>
+ <dd>또 다른 액티비티가 전경에 나와 있고 사용자가 이에 초점을 맞추고 있지만,
+이 프래그먼트가 있는 액티비티도 여전히 표시되어 있습니다(전경의 액티비티가 부분적으로 투명하거나
+전체 화면을 뒤덮지 않습니다).</dd>
+
+ <dt><i>정지됨</i></dt>
+ <dd>프래그먼트가 표시되지 않습니다. 호스트 액티비티가 정지되었거나
+프래그먼트가 액티비티에서 제거되었지만 백 스택에 추가되었습니다. 정지된 프래그먼트도
+여전히 표시는 됩니다(모든 상태 및 구성원 정보를 시스템이 보존합니다). 하지만, 사용자에게는
+더 이상 표시되지 않으며 액티비티를 종료하면 이것도 종료됩니다.</dd>
+</dl>
+
+<p>이번에도 액티비티와 마찬가지로, 프래그먼트의 상태를 보존하려면 {@link
+android.os.Bundle}을 사용합니다. 이는 혹시나 액티비티의 프로세스가 종료되고 액티비티를
+다시 만들 때 해당 프래그먼트의 상태를 복구해야 할 필요가 있을 때를 대비하는 것입니다. 상태를 저장하려면 프래그먼트의 {@link
+android.app.Fragment#onSaveInstanceState onSaveInstanceState()} 콜백 중에 저장할 수 있고, 복구는
+{@link android.app.Fragment#onCreate onCreate()}, {@link
+android.app.Fragment#onCreateView onCreateView()} 또는 {@link
+android.app.Fragment#onActivityCreated onActivityCreated()} 중 한 가지가 진행되는 동안 할 수 있습니다. 상태 저장에 관한 자세한 정보는
+<a href="{@docRoot}guide/components/activities.html#SavingActivityState">액티비티</a>
+문서를 참조하십시오.</p>
+
+<p>액티비티와 프래그먼트의 수명 주기에서 가장 중대한 차이점은
+해당되는 백 스택에 저장되는 방법입니다. 액티비티는 중단되었을 때 시스템이 관리하는
+액티비티 백 스택 안에 배치되는 것이 기본입니다(따라서 사용자가 <em>뒤로</em> 버튼을 사용하여 다시 이 액티비티로
+뒤로 탐색할 수 있습니다. 이 내용은 <a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업 및 백 스택</a>에서 설명하였습니다).
+하지만, 프래그먼트가 호스트 액티비티가 관리하는 백 스택 안에 배치되는 것은 해당 인스턴스를 저장하라고 명시적으로 요청하는 경우뿐입니다.
+이때 프래그먼트를 제거하는 트랜잭션 중 {@link
+android.app.FragmentTransaction#addToBackStack(String) addToBackStack()}을
+호출합니다.</p>
+
+<p>이것만 제외하면, 프래그먼트 수명 주기를 관리하는 것은 액티비티의 수명 주기를 관리하는 것과
+아주 비슷합니다. 따라서, <a href="{@docRoot}guide/components/activities.html#Lifecycle">액티비티
+수명 주기 관리</a>에 쓰이는 실례가 프래그먼트에도 똑같이 적용되는 것입니다. 하지만 또 한 가지 이해해두어야 하는 것이 있습니다. 즉,
+액티비티의 수명이 프래그먼트의 수명에 어떤 영향을 미치는지를 알아두어야 합니다.</p>
+
+<p class="caution"><strong>주의:</strong> {@link android.app.Fragment} 내에서 {@link android.content.Context}
+객체가 필요한 경우, {@link android.app.Fragment#getActivity()}를 호출하면 됩니다.
+그러나 {@link android.app.Fragment#getActivity()}를 호출하는 것은 프래그먼트가 액티비티에
+ 첨부되어 있는 경우뿐이니 유의하십시오. 프래그먼트가 아직 첨부되지 않았거나 수명 주기가 끝날 무렵 분리된 경우,
+{@link android.app.Fragment#getActivity()}가 null을 반환합니다.</p>
+
+
+<h3 id="CoordinatingWithActivity">액티비티 수명 주기와 조화</h3>
+
+<p>프래그먼트가 있는 액티비티의 수명 주기는 해당 프래그먼트의 수명 주기에 직접적인
+영향을 미칩니다. 따라서 액티비티에 대한 각 수명 주기 콜백이 각 프래그먼트에 대한 비슷한 콜백을
+유발합니다. 예를 들어 액티비티가 {@link android.app.Activity#onPause}를 받으면,
+해당 액티비티 내의 각 프래그먼트가 {@link android.app.Fragment#onPause}를 받습니다.</p>
+
+<p>하지만 프래그먼트에는 몇 가지 수명 주기 콜백이 더 있습니다. 이것은 액티비티와의
+고유한 상호 작용을 다루어 프래그먼트의 UI를 구축하고 소멸시키는 것과 같은
+작업을 수행합니다. 이러한 추가적인 콜백 메서드를 예로 들면 다음과 같습니다.</p>
+
+<dl>
+ <dt>{@link android.app.Fragment#onAttach onAttach()}</dt>
+ <dd>프래그먼트가 액티비티와 연관되어 있었던 경우 호출됩니다(여기에서 {@link
+android.app.Activity}가 전달됩니다).</dd>
+ <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
+ <dd>프래그먼트와 연관된 보기 계층을 생성하기 위해 호출됩니다.</dd>
+ <dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt>
+ <dd>액티비티의 {@link android.app.Activity#onCreate
+onCreate()} 메서드가 반환되면 호출됩니다.</dd>
+ <dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt>
+ <dd>프래그먼트와 연관된 보기 계층이 제거되는 중일 때 호출됩니다.</dd>
+ <dt>{@link android.app.Fragment#onDetach onDetach()}</dt>
+ <dd>프래그먼트가 액티비티와 연결이 끊어지는 중일 때 호출됩니다.</dd>
+</dl>
+
+<p>호스트 액티비티의 영향을 받을 프래그먼트 수명 주기의 흐름은 그림 3에서
+확인하십시오. 이 그림을 보면 액티비티의 각 연속된 상태가 프래그먼트가 어느
+콜백 메서드를 받게 되는지 결정 짓는다는 것을 볼 수 있습니다. 예를 들어 액티비티가 자신의 {@link
+android.app.Activity#onCreate onCreate()} 콜백을 받은 경우, 해당 액티비티 안에 있는 프래그먼트는
+{@link android.app.Fragment#onActivityCreated onActivityCreated()} 콜백을 받을 뿐입니다.</p>
+
+<p>액티비티가 재개된 상태에 도달하면 자유자재로 프래그먼트를 액티비티에 추가하거나 액티비티에서
+제거해도 됩니다. 따라서, 액티비티가 재개된 상태에 있는 동안에만 프래그먼트의 수명 주기를
+독립적으로 변경할 수 있는 것입니다.</p>
+
+<p>그러나 액티비티가 재개된 상태를 떠나면 액티비티는 다시 프래그먼트를 그 수명 주기 안으로
+밀어넣습니다.</p>
+
+
+
+
+<h2 id="Example">예</h2>
+
+<p>이 문서에서 논의한 모든 것을 한 번에 모아 보기 위해, 다음은 두 개의 프래그먼트를 사용하여
+창이 두 개인 레이아웃을 생성하는 액티비티를 예시로 나타낸 것입니다. 아래의 액티비티에 포함된
+한 프래그먼트는 셰익스피어 희곡 제목 목록을 표시하고, 또 다른 하나는 목록에서 선택했을 때
+해당 희곡의 요약을 표시합니다. 또한 화면 구성을 근거로 프래그먼트를 여러 가지로 구성하여 제공하는 방법도
+보여줍니다.</p>
+
+<p class="note"><strong>참고:</strong> 이 액티비티에 대한 완전한 소스 코드는
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
+FragmentLayout.java}</a>에서 이용하실 수 있습니다.</p>
+
+<p>주요 액티비티는 {@link
+android.app.Activity#onCreate onCreate()} 중에 일반적인 방식으로 레이아웃을 적용합니다.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main}
+
+<p>적용된 레이아웃은 {@code fragment_layout.xml}입니다.</p>
+
+{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout}
+
+<p>시스템은 이 레이아웃을 사용하여 액티비티가 레이아웃을 로딩하자마자 {@code TitlesFragment}를 초기화합니다(이것이 희곡 제목을
+목록으로 나열합니다). 반면 {@link android.widget.FrameLayout}
+(희곡 요약을 표시하는 프래그먼트가 배치될 곳)은 화면 오른쪽에 있는
+공간을 차지하기는 하지만 처음에는 텅 빈 상태로 유지됩니다. 아래에서 볼 수 있듯이, 사용자가 해당 목록에서
+항목을 하나 선택해야만 프래그먼트가 {@link android.widget.FrameLayout} 안에 배치됩니다.</p>
+
+<p>그러나 희곡 목록과 요약을 둘 다 나란히 표시할 만큼 너비가 넓지 않은
+화면 구성도 있습니다. 따라서 위의 레이아웃은 가로 방향 화면 구성에만 사용되며,
+이를 {@code res/layout-land/fragment_layout.xml}에 저장하여 씁니다.</p>
+
+<p>그러므로 화면이 세로 방향으로 구성된 경우, 시스템은 다음 레이아웃을 적용합니다. 이것은
+{@code res/layout/fragment_layout.xml}에 저장되어 있습니다.</p>
+
+{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
+
+<p>이 레이아웃에는 {@code TitlesFragment}만 포함되어 있습니다. 이는 다시 말해 기기가 세로 방향인 경우에는
+희곡 제목 목록만 표시된다는 뜻입니다. 따라서 사용자가 이 구성에서 목록 항목을 하나 클릭하면,
+애플리케이션이 두 번째 프래그먼트를 로딩하는 대신 새 액티비티를 시작하여 요약을
+표시하게 됩니다.</p>
+
+<p>다음으로, 프래그먼트 클래스에서 이것을 달성하는 방법을 보시겠습니다. 첫 번째가 {@code
+TitlesFragment}로, 셰익스피어 희곡 제목 목록을 표시하는 것입니다. 이 프래그먼트는 {@link
+android.app.ListFragment}를 확장하며 목록 보기 작업의 대부분을 처리하기 위해 여기에 의존합니다.</p>
+
+<p>이 코드를 살펴보면서 사용자가 목록 항목을 클릭하면 일어날 수 있는 두 가지 동작이
+있다는 점을 눈여겨 보십시오. 두 레이아웃 중 어느 것이 활성화 상태인지에 따라
+같은 액티비티 내에서 세부 사항을 표시하기 위해 새 프래그먼트를 생성하거나 표시할 수도 있고(프래그먼트를 {@link
+android.widget.FrameLayout}에 추가함으로써), 새 액티비티를 시작할 수도 있습니다(프래그먼트를 표시할 수 있는 곳).</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles}
+
+<p>두 번째 프래그먼트인 {@code DetailsFragment}는 {@code TitlesFragment}에서 가져온 목록에서 선택한 항목에 대한 희곡 요약을
+표시하는 것입니다.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details}
+
+<p>{@code TitlesFragment} 클래스에서 다룬 것을 되살려 보면, 사용자가 목록 항목을 클릭하고
+현재 레이아웃이 {@code R.id.details} 보기를 포함하지 <em>않는</em> 경우(이 보기가
+{@code DetailsFragment}가 속하는 곳임), 애플리케이션은 항목의 내용을 표시하기 위해 {@code DetailsActivity}
+ 액티비티를 시작하게 됩니다.</p>
+
+<p>다음은 화면이 세로 방향으로 구성되어 있을 때 선택한 희곡의 요약을 표시하기 위해 단순히 {@code DetailsFragment}를
+ 포함할 뿐인 {@code DetailsActivity}입니다.</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
+details_activity}
+
+<p>이 액티비티는 구성이 가로 방향인 경우 알아서 종료한다는 점을 눈여겨 보십시오. 따라서
+주요 액티비티가 작업을 인계 받아 {@code DetailsFragment}를 {@code TitlesFragment}와 함께 표시할 수 있는 것입니다.
+이것은 사용자가 세로 방향 구성에서 {@code DetailsActivity}를 시작했지만
+그런 다음 가로 방향으로 돌리는 경우(현재 액티비티를 다시 시작함) 일어날 수 있습니다.</p>
+
+
+<p>프래그먼트 사용에 대한 더 많은 샘플(및 이 예시에 대한 완전한 소스 파일)을 보시려면
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
+ApiDemos</a>에서 이용할 수 있는 API Demos 샘플 앱을 참조하십시오(<a href="{@docRoot}resources/samples/get.html">샘플 SDK 구성 요소</a>에서 다운로드할 수 있습니다).</p>
+
+
diff --git a/docs/html-intl/intl/ko/guide/components/fundamentals.jd b/docs/html-intl/intl/ko/guide/components/fundamentals.jd
new file mode 100644
index 000000000000..608b5a2cba1b
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/fundamentals.jd
@@ -0,0 +1,480 @@
+page.title=애플리케이션 기본 항목
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+<li><a href="#Components">앱 구성 요소</a>
+ <ol>
+ <li><a href="#ActivatingComponents">구성 요소 활성화</a></li>
+ </ol>
+</li>
+<li><a href="#Manifest">매니페스트 파일</a>
+ <ol>
+ <li><a href="#DeclaringComponents">구성 요소 선언</a></li>
+ <li><a href="#DeclaringRequirements">앱 요구 사항 선언</a></li>
+ </ol>
+</li>
+<li><a href="#Resources">앱 리소스</a></li>
+</ol>
+</div>
+</div>
+
+<p>Android 앱은 Java 프로그래밍 언어로 작성됩니다. Android SDK 도구는
+코드를 컴파일링하여 모든 데이터 및 리소스 파일과 함께 하나의 APK로 만듭니다. 이것은 즉, <i>Android 패키지</i>
+를 뜻하며, 이는 일종의 {@code .apk} 접미사가 있는 아카이브 파일입니다. 한 개의 APK 파일에는
+Android 앱의 모든 콘텐츠가 들어 있으며 이 파일이 바로 Android로 구동하는 기기가 앱을 설치할 때 사용하는 파일입니다.</p>
+
+<p>Android 앱은 일단 기기에 설치되고 나면 각자 나름의 보안 샌드박스 안에 살게 됩니다. </p>
+
+<ul>
+ <li>Android 운영 체제는 멀티 사용자 Linux 시스템으로, 여기서 각 앱은 각기 다른 사용자와
+같습니다.</li>
+
+<li>기본적으로 시스템이 각 앱에 고유한 Linux ID를 할당합니다(이 ID는 시스템만
+사용할 수 있으며 앱은 이것을 알지 못합니다). 시스템은 앱 안의 모든 파일에 대해 권한을 설정하여
+해당 앱에 할당된 사용자 ID만 이에 액세스할 수 있도록 합니다. </li>
+
+<li>각 프로세스에는 나름의 가상 머신(VM)이 있고, 그렇기 때문에 한 앱의 코드가 다른 여러 앱과는 격리된 상태로
+실행됩니다.</li>
+
+<li>기본적으로 모든 앱이 나름의 Linux 프로세스에서 실행됩니다. Android는 앱의 구성 요소 중
+어느 것이라도 실행해야 하는 경우 프로세스를 시작하고, 이것이 더 이상 필요 없어지거나 시스템이 다른 앱을 위해
+메모리를 회복해야 하는 경우 해당 프로세스를 종료합니다.</li>
+</ul>
+
+<p>Android 시스템은 이런 방식으로 <em>최소 특권의 원리</em>를 구현하는 것입니다. 다시 말해,
+각 앱은 기본적으로 자신의 작업을 수행하기 위해 필요한 구성 요소에만 액세스 권한을 가지고
+그 이상은 허용되지 않습니다. 이렇게 하면 대단히 안전한 환경이 만들어져 앱이 시스템에서
+자신이 권한을 부여 받지 못한 부분에는 액세스할 수 없게 됩니다.</p>
+
+<p>그러나, 앱이 다른 여러 앱과 데이터를 공유하는 것과 앱이 시스템 서비스에 액세스하는 데에는
+여러 가지 방법이 있습니다.</p>
+
+<ul>
+ <li>두 개의 앱이 같은 Linux 사용자 ID를 공유하도록 설정할 수도 있습니다. 이 경우
+두 앱은 서로의 파일에 액세스할 수 있게 됩니다. 시스템 리소스를 절약하려면, 같은 사용자 ID를 가진 앱이
+같은 Linux 프로세스에서 실행되도록 설정하고 같은 VM을 공유하도록 할 수도 있습니다(이들 앱은 같은 인증서로
+서명해야 합니다).</li>
+ <li>앱은 사용자의 연락처, SMS 메시지, 마운트 가능한 저장소(SD 카드),
+카메라, Bluetooth를 비롯하여 이외에도 여러 가지 기기 데이터에 액세스할 권한을 요청할 수 있습니다. 모든
+앱 권한은 설치 시점에 사용자가 허용해야 합니다.</li>
+</ul>
+
+<p>이렇게 해서 Android 앱이 시스템 내에 어떤 식으로 존재하는지 기본 정보를 알아보았습니다. 이 문서의
+나머지 부분에서 소개될 내용은 다음과 같습니다.</p>
+<ul>
+ <li>앱을 정의하는 핵심 프레임워크 구성 요소.</li>
+ <li>구성 요소를 선언하고 앱에 맞는 필수 기기 특징을 선언할 수 있는 매니페스트
+파일.</li>
+ <li>앱 코드로부터 별도로 분리되어 있으며 앱이 다양한 기기 구성에 맞게 자신의 행동을
+안정적으로 최적화할 수 있도록 해주는 리소스.</li>
+</ul>
+
+
+
+<h2 id="Components">앱 구성 요소</h2>
+
+<p>앱 구성 요소는 Android 앱을 이루는 가장 기본적인 구성 단위입니다. 각
+구성 요소는 시스템이 앱으로 들어올 수 있는 각기 다른 통과 지점을 나타냅니다. 구성 요소 중에는
+실제 사용자가 쓸 수 있는 진입 지점이 아닌 것도 있고, 일부는 서로에게 의존하지만,
+각각의 구성 요소는 따로 떨어진 엔티티로서 존재하며 각기 특정한 역할을 수행합니다. 즉 하나하나가
+앱의 전반적인 행동을 정의하는 데 유용한 고유한 구성 단위인 것입니다.</p>
+
+<p>앱 구성 요소에는 네 가지 서로 다른 유형이 있습니다. 각 유형이 뚜렷한 목적을 가지고 있으며
+각자 나름의 수명 주기가 있어 구성 요소의 생성 및 소멸 방식을 정의합니다.</p>
+
+<p>다음은 네 가지 유형의 앱 구성 요소를 나타낸 것입니다.</p>
+
+<dl>
+
+<dt><b>액티비티</b></dt>
+
+<dd>통상 <i>액티비티</i> 라고 하면, 사용자 인터페이스가 있는 화면 하나를 나타냅니다. 예를 들어
+이메일 앱이라면 새 이메일 목록을 표시하는 액티비티가 하나 있고,
+이메일을 작성하는 액티비티가 또 하나, 그리고 이메일을 읽는 데 쓰는 액티비티가 또 하나 있을 수 있습니다. 여러
+액티비티가 함께 작동하여 해당 이메일 앱에서 짜임새 있는 사용자 환경을 형성하는 것은 사실이지만, 각자 서로와는
+독립적인 형태입니다. 따라서, 다른 앱이 이와 같은 액티비티 중 어느 것이라도 하나만
+시작할 수 있습니다(이메일 앱이 그렇게 하도록 허용하는 경우). 예를 들어, 카메라 앱이라면 이메일 앱 안의
+액티비티를 시작하여 새 메일을 작성하도록 해서 사용자가 사진을 공유하도록 할 수 있습니다.
+
+<p>액티비티는 {@link android.app.Activity}의 하위 클래스로 구현되며 이에 대한 더 자세한 내용은
+<a href="{@docRoot}guide/components/activities.html">액티비티</a>
+개발자 가이드에서 확인하실 수 있습니다.</p>
+</dd>
+
+
+<dt><b>서비스</b></dt>
+
+<dd>통상 <i>서비스</i> 라고 하면 배경에서 실행되는 구성 요소로, 오랫동안 실행되는
+작업을 수행하거나 원격 프로세스를 위한 작업을 수행하는 것입니다. 서비스는
+사용자 인터페이스를 제공하지 않습니다. 예를 들어 서비스는 사용자가 다른 앱에 있는 동안에 배경에서 음악을 재생할 수도 있고,
+아니면 사용자와 액티비티 사이의 상호 작용을 차단하지 않고 네트워크를 가로질러
+데이터를 가져올 수도 있습니다. 또 다른 구성 요소(예: 액티비티)가 서비스를 시작한 다음
+실행되도록 두거나 자신에게 바인딩하여 상호 작용하도록 할 수도 있습니다.
+
+<p>서비스는 {@link android.app.Service}의 하위 클래스로 구현되며 이에 대한 더 자세한 내용은
+<a href="{@docRoot}guide/components/services.html">서비스</a>
+개발자 가이드에서 확인하실 수 있습니다.</p>
+</dd>
+
+
+<dt><b>콘텐츠 제공자</b></dt>
+
+<dd>통상 <i>콘텐츠 제공자</i> 는 공유된 앱 데이터 집합을 관리합니다. 데이터는 파일 시스템이나 SQLite 데이터베이스,
+또는 웹이나 기타 영구적인 저장소 위치 중 앱이 액세스할 수 있는 곳이라면 어디에든 저장할 수
+있습니다. 다른 여러 앱은 콘텐츠 제공자를 통해 해당 데이터를 쿼리하거나, 심지어는 수정할 수도
+있습니다(콘텐츠 제공자가 그렇게 하도록 허용하는 경우). 예를 들어, Android 시스템은 사용자의 연락처 정보를
+관리하는 콘텐츠 제공자를 제공합니다. 따라서, 적절한 권한을 가진 앱이라면
+어떤 것이든 해당 콘텐츠 제공자의 일부를 쿼리하여(예를 들어 {@link
+android.provider.ContactsContract.Data} 등) 특정한 사람에 대한 정보를 읽고 쓸 수 있습니다.
+
+<p>콘텐츠 제공자는 앱에서 비공개이며 공유되지 않는 데이터를 읽고 쓰는 데에도
+유용합니다. 예를 들어 <a href="{@docRoot}resources/samples/NotePad/index.html">메모장</a> 샘플 앱은 메모한 내용을 저장하는 데
+콘텐츠 제공자를 사용합니다.</p>
+
+<p>콘텐츠 제공자는 {@link android.content.ContentProvider}의
+하위 클래스로 구현되며, 다른 앱이 트랜잭션을 수행할 수 있도록 활성화하는 표준 API 집합을
+구현해야 합니다. 자세한 내용은 <a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a> 개발자
+가이드를 참조하십시오.</p>
+</dd>
+
+
+<dt><b>브로드캐스트 수신기</b></dt>
+
+<dd>통상 <i>브로드캐스트 수신기</i> 는 시스템 전체에 대한 브로드캐스트 공지에 응답하는 구성 요소를
+말합니다. 대다수의 브로드캐스트는 시스템에서 시작합니다. 예를 들어, 화면이 꺼졌다거나
+배터리 잔량이 부족하다거나, 사진을 캡처했다는 것을 알리는 브로드캐스트가 있습니다.
+앱도 브로드캐스트를 시작합니다. 예를 들어, 기기에 몇 가지 데이터를 다운로드하여 다른 앱도 사용할 수 있다는
+사실을 다른 여러 앱에게 알리는 것입니다. 브로드캐스트 수신기는 사용자 인터페이스를 표시하지 않지만,
+<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">상태 표시줄 알림을 생성</a>하여
+사용자에게 브로드캐스트 이벤트가 발생했다고 알릴 수 있습니다. 다만 브로드캐스트 수신기는
+그저 다른 구성 요소로의 "게이트웨이"인 경우가 더 보편적이고, 극소량의 작업만 수행하도록 만들어진 경우가 많습니다. 예컨대
+서비스를 시작하여 이벤트를 근거로 한 어떤 작업을 수행하도록 할 수 있습니다.
+
+<p>브로드캐스트 수신기는 {@link android.content.BroadcastReceiver}의
+하위 클래스로 구현되며 각 브로드캐스트는 {@link android.content.Intent} 객체로 전달됩니다. 자세한 정보는
+{@link android.content.BroadcastReceiver} 클래스를 참조하십시오.</p>
+</dd>
+
+</dl>
+
+
+
+<p>Android 시스템 디자인의 독특한 점으로 어떤 앱이든 다른 앱의 구성 요소를 시작할 수 있다는 점을
+들 수 있습니다. 예를 들어 사용자가 기기 카메라로 사진을 캡처하기를 바라는 경우,
+그런 작업을 수행하는 또 다른 앱이 있을 가능성이 높습니다. 그러면 사진을 캡처하는 액티비티를 직접 개발하는 대신
+여러분의 앱이 그 앱을 사용하도록 하면 됩니다. 카메라 앱에
+통합하기는커녕 카메라 앱의 코드에 연결시킬 필요조차도 없습니다.
+그 대신, 그저 사진을 캡처하는 카메라 앱 안의 해당 액티비티를 시작하기만 하면
+됩니다. 작업이 완료되면 사진이 앱으로 반환되기까지 하여 바로 사용할 수 있습니다. 사용자에게는,
+마치 카메라가 여러분의 앱의 일부분인 것처럼 보입니다.</p>
+
+<p>시스템이 구성 요소를 시작하는 경우, 그 앱에 대한 프로세스를 시작하는 것이며(이미
+실행 중이지 않은 경우), 해당 구성 요소에 필요한 클래스를 인스턴트화하는 것입니다. 예를 들어 여러분의 앱이
+카메라 앱 내에서 사진을 캡처하는 액티비티를 시작한다고 하면, 해당 액티비티는
+여러분 앱의 프로세스가 아니라 카메라 앱에 속한 프로세스에서 실행됩니다.
+따라서 대부분의 다른 시스템에서와는 달리 Android 앱에는 단일한 진입
+지점이 없습니다(예를 들어 {@code main()} 기능이 없습니다).</p>
+
+<p>시스템이 각 앱을 별도의 프로세스에서 실행하며 다른 앱에 대한 액세스를 제한하는
+파일 권한을 가지고 실행하기 때문에 여러분의 앱은 또 다른 앱에서 곧바로 구성 요소를
+활성화할 수는 없습니다. 하지만 Android 시스템은 할 수 있습니다. 그래서 또 다른 앱에 있는
+구성 요소를 활성화하려면 시스템에 메시지를 전달하여 특정 구성 요소를 시작하고자 하는 <em>인텐트</em>를
+밝혀야 합니다. 그러면 시스템이 대신 해당 구성 요소를 활성화해줍니다.</p>
+
+
+<h3 id="ActivatingComponents">구성 요소 활성화</h3>
+
+<p>네 가지 구성 요소 중 세 가지&mdash;액티비티, 서비스 및
+브로드캐스트 수신기&mdash;는 일명 <em>인텐트</em>라고 하는 비동기식 메시지가 활성화합니다.
+인텐트는 각각의 구성 요소를 런타임에 서로 바인딩하며(다른 구성 요소로부터 작업을 요청하는
+일종의 메신저로 생각하면 됩니다), 이는 구성 요소가 여러분의 앱에 속하든 아니든
+무관합니다.</p>
+
+<p>인텐트는 {@link android.content.Intent} 객체로 생성되며, 이것이
+특정 구성 요소를 활성화할지 아니면 구성 요소의 특정 <em>유형</em>을 활성화할지를 나타내는 메시지를 정의합니다. 인텐트는
+각각 명시적이거나 암시적일 수 있습니다.</p>
+
+<p>액티비티와 서비스의 경우, 인텐트는 수행할 작업을 정의하며(예를 들어 무언가를 '보기" 또는
+"보내기"), 작업을 수행할 데이터의 URI를 나타낼 수 있습니다(시작되는 구성 요소가 알아야 할 것은
+이외에도 많이 있습니다). 예를 들어, 인텐트는 액티비티에 이미지를 표시하거나 웹 페이지를 열라는 요청을
+전달할 수 있습니다. 어떤 경우에는 액티비티를 시작하여
+결과를 받아오도록 할 수 있습니다. 이런 경우 이 액티비티는
+{@link android.content.Intent}로 결과를 반환하기도 합니다(예를 들어, 사용자가
+개인적인 연락처를 선택하도록 한 다음 그것을 반환하도록 하는 인텐트를 발행할 수 있습니다&mdash;반환 인텐트에
+선택한 연락처를 가리키는 URI가 포함됩니다).</p>
+
+<p>브로드캐스트 수신기의 경우, 인텐트는 단순히 브로드캐스트될 알림을
+정의할 뿐입니다(예를 들어, 기기 배터리 잔량이 낮다는 것을 나타내는 브로드캐스트에는
+"배터리 부족"을 나타내는 알려진 작업 문자열만 포함됩니다).</p>
+
+<p>남은 하나의 구성 요소 유형, 즉 콘텐츠 제공자는 인텐트가 활성화하지 않습니다. 그보다는
+{@link android.content.ContentResolver}로부터의 요청으로 지정되면 활성화됩니다. 콘텐츠
+확인자는 콘텐츠 제공자와의 모든 직접적인 트랜잭션을 처리하여
+제공자와의 트랜잭션을 수행하는 구성 요소가 그런 일을 하지 않아도 되게 하고, 그 대신 {@link
+android.content.ContentResolver} 객체에서 메서드를 호출합니다. 이렇게 되면 콘텐츠 제공자와
+정보를 요청하는 구성 요소 사이에 추상화 계층이 하나 남습니다(보안 목적).</p>
+
+<p>각 유형의 구성 요소를 활성화하는 데에는 각기 별도의 메서드가 있습니다.</p>
+<ul>
+ <li>액티비티를 시작하려면(아니면 무언가 새로운 할 일을 주려면)
+{@link android.content.Intent}를 {@link android.content.Context#startActivity
+startActivity()} 또는 {@link android.app.Activity#startActivityForResult startActivityForResult()}에
+전달하면 됩니다(액티비티가 결과를 반환하기를 원하는 경우).</li>
+ <li>서비스를 시작하려면(또는 진행 중인 서비스에 새로운 지침을 주려면)
+{@link android.content.Intent}를 {@link android.content.Context#startService
+startService()}에 전달하면 됩니다. 아니면 {@link android.content.Intent}를
+{@link android.content.Context#bindService bindService()}에 전달하여 서비스에 바인딩할 수도 있습니다.</li>
+ <li>브로드캐스트를 시작하려면 {@link android.content.Intent}를
+{@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, {@link
+android.content.Context#sendOrderedBroadcast(Intent, String) sendOrderedBroadcast()} 또는 {@link
+android.content.Context#sendStickyBroadcast sendStickyBroadcast()}와 같은 메서드에 전달하면 됩니다.</li>
+ <li>콘텐츠 제공자에 쿼리를 수행하려면 {@link android.content.ContentResolver}에서 {@link
+android.content.ContentProvider#query query()}를 호출하면 됩니다.</li>
+</ul>
+
+<p>인텐트 사용에 관한 자세한 정보는 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및
+인텐트 필터</a>문서를 참조하십시오. 특정 구성 요소를 활성화하는 데 관한 자세한 정보 또한 다음 문서에
+제공되어 있습니다. <a href="{@docRoot}guide/components/activities.html">액티비티</a>, <a href="{@docRoot}guide/components/services.html">서비스</a>, {@link
+android.content.BroadcastReceiver} 및 <a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a>.</p>
+
+
+<h2 id="Manifest">매니페스트 파일</h2>
+
+<p>Android 시스템이 앱 구성 요소를 시작하려면 시스템은 우선 해당 구성 요소가
+존재하는지 알아야 합니다. 그러기 위해 앱의 {@code AndroidManifest.xml} 파일을 읽습니다(즉 "매니페스트"
+파일). 앱은 이 파일 안에 모든 구성 요소를 선언해야 하며, 이 파일은 앱 프로젝트 디렉터리의 루트에
+있어야 합니다.</p>
+
+<p>매니페스트는 앱의 구성 요소를 선언하는 것 이외에도 수많은 역할을 합니다.
+예를 들면 다음과 같습니다.</p>
+<ul>
+ <li>앱이 요구하는 모든 사용자 권한 식별(예: 인터넷 액세스 또는 사용자의 연락처로의
+읽기 액세스)</li>
+ <li>앱이 어느 API를 사용하는지를 근거로 하여 앱에서 요구하는 최소 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API 레벨</a>
+선언</li>
+ <li>앱에서 사용하거나 필요로 하는 하드웨어 및 소프트웨어 기능 선언(예: 카메라,
+블루투스 서비스 또는 멀티터치 화면 등)</li>
+ <li>앱이 링크되어야 하는 API 라이브러리(Android 프레임워크
+API 제외)(예: <a href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">Google Maps
+라이브러리</a>)</li>
+ <li>그 외 기타 등등</li>
+</ul>
+
+
+<h3 id="DeclaringComponents">구성 요소 선언</h3>
+
+<p>매니페스트의 주요 작업은 시스템에 앱의 구성 요소에 대해 알리는 것입니다. 예를 들어
+매니페스트 파일은 액티비티를 다음과 같이 선언할 수 있습니다. </p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;manifest ... &gt;
+ &lt;application android:icon="@drawable/app_icon.png" ... &gt;
+ &lt;activity android:name="com.example.project.ExampleActivity"
+ android:label="@string/example_label" ... &gt;
+ &lt;/activity&gt;
+ ...
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p><code><a
+href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+요소에서 {@code android:icon} 속성은 앱을 식별하는 아이콘에 대한 리소스를
+가리킵니다.</p>
+
+<p><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> 요소에서는,
+{@code android:name} 속성이 {@link
+android.app.Activity} 하위 클래스의 완전히 정규화된 클래스 이름을 나타내며 {@code android:label} 속성은 액티비티의
+사용자에게 표시되는 레이블로 사용할 문자열을 나타냅니다.</p>
+
+<p>모든 앱 구성 요소를 이렇게 선언해야 합니다.</p>
+<ul>
+ <li>액티비티는
+<code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> 요소</li>
+ <li>서비스는
+<code><a
+href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code> 요소</li>
+ <li>브로드캐스트 수신기는
+<code><a
+href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code> 요소</li>
+ <li>콘텐츠 제공자는
+<code><a
+href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> 요소</li>
+</ul>
+
+<p>액티비티, 서비스를 비롯하여 소스에는 포함시키지만 매니페스트에서는 선언하지 않는
+콘텐츠 제공자는 시스템에 표시되지 않으며, 따라서 실행될 수 없습니다. 그러나
+브로드캐스트
+ 수신기는 매니페스트에서 선언해도 되고 코드를 사용해(
+{@link android.content.BroadcastReceiver} 객체로) 동적으로 생성한 다음 시스템에 등록해도 됩니다. 이때
+{@link android.content.Context#registerReceiver registerReceiver()}를 호출하는 방법을 씁니다.</p>
+
+<p>앱에 맞는 매니페스트 파일을 구성하는 방법에 대한 자세한 내용은 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml 파일</a>을
+ 참조하십시오. </p>
+
+
+
+<h3 id="DeclaringComponentCapabilities">구성 요소 기능 선언</h3>
+
+<p>위에서 논한 바와 같이, <a href="#ActivatingComponents">활성화 상태의 구성 요소</a>에서는
+{@link android.content.Intent}를 사용하여 액티비티, 서비스 및 브로드캐스트 수신기를 시작할 수 있습니다. 그렇게 하려면
+대상 구성 요소를 인텐트 내에서 명시적으로 명명하면 됩니다(구성 요소 클래스 이름을 사용). 그러나,
+인텐트의 진정한 힘은 <em>암시적 인텐트</em>의 개념에서 발휘됩니다. 암시적 인텐트는
+그저 수행할 작업의 유형을 설명할 뿐이며(또한, 선택 사항으로, 해당 작업을 수행하고자 하는
+데이터 위치도) 시스템에 기기에서 작업을 수행할 수 있는 구성 요소를 찾아
+시작하도록 해줍니다. 인텐트가 설명한 작업을 수행할 수 있는 구성 요소가 여러 개인 경우,
+어느 것을 사용할지 사용자가 선택합니다.</p>
+
+<p>시스템이 인텐트에 응답할 수 있는 구성 요소를 식별하는 방법은 수신한 인텐트를
+ <i>인텐트 필터</i> 와 비교하는 것입니다. 이 인텐트 필터는 기기의 다른 여러 앱의 매니페스트
+파일이 제공합니다.</p>
+
+<p>앱의 매니페스트에서 액티비티를 선언하는 경우, 선택 사항으로
+해당 액티비티의 기능을 선언하는 인텐트 필터를 포함시켜서 다른 앱으로부터의 인텐트에
+응답할 수 있도록 할 수 있습니다. 구성 요소에 대한 인텐트 필터를 선언하려면
+<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> 요소를 해당 구성 요소의 선언 요소 하위로 추가하면 됩니다.</p>
+
+<p>예를 들어, 새 이메일을 작성하는 데 쓰는 액티비티가 있는 이메일 앱을 구축했다고 가정합시다. 이때 "전송" 인텐트에
+응답하는 인텐트 필터를 선언하려면(새 이메일을 전송하기 위해) 다음과 같이 하면 됩니다.</p>
+<pre>
+&lt;manifest ... >
+ ...
+ &lt;application ... &gt;
+ &lt;activity android:name="com.example.project.ComposeEmailActivity">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND" />
+ &lt;data android:type="*/*" />
+ &lt;category android:name="android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+ &lt;/activity>
+ &lt;/application&gt;
+&lt;/manifest>
+</pre>
+
+<p>그런 다음, 다른 앱이 {@link
+android.content.Intent#ACTION_SEND} 작업을 가진 인텐트를 생성하여 그것을 {@link android.app.Activity#startActivity
+startActivity()}로 전달하면 시스템이 여러분의 액티비티를 시작하여 사용자가 이메일을 임시 보관하고 전송할 수
+있습니다.</p>
+
+<p>인텐트 필터 생성에 관한 자세한 내용은 <a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a> 문서를 참조하십시오.
+</p>
+
+
+
+<h3 id="DeclaringRequirements">앱 요구 사항 선언</h3>
+
+<p>Android로 구동되는 기기는 수없이 많지만 모두 똑같은 특징을 갖고 같은
+기능을 제공하는 것은 아닙니다. 앱이 필요로 하는 기능이 부족한 기기에 앱을 설치하게 되는 불상사를 방지하려면,
+앱이 지원하는 기기 유형에 대한 프로필을 명확하게 정의하는 것이 중요합니다.
+그러려면 매니페스트 파일에 기기와 소프트웨어 요구 사항을
+선언하면 됩니다. 이와 같은 선언은 대부분 정보성일 뿐이며 시스템은 이를 읽지 않는 것이 일반적이지만,
+Google Play와 같은 외부 서비스는 사용자가 본인의 기기에서 앱을 검색할 때 필터링을 제공하기 위해
+이와 같은 선언도 읽습니다.</p>
+
+<p>예를 들어, 앱에 카메라가 필요하고 Android 2.1부터 도입된 API를 사용하는 경우(<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API 레벨</a> 7)
+이과 같은 내용을 매니페스트 파일에 요구 사항으로 선언하려면 다음과 같이 합니다.</p>
+
+<pre>
+&lt;manifest ... >
+ &lt;uses-feature android:name="android.hardware.camera.any"
+ android:required="true" />
+ &lt;uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
+ ...
+&lt;/manifest>
+</pre>
+
+<p>이제 카메라가 <em>없고</em> Android 버전이 2.1 <em>이하</em>인 기기는
+Google Play에서 여러분의 앱을 설치할 수 없습니다.</p>
+
+<p>그러나, 앱이 카메라를 사용하기는 하지만 꼭
+<em>필요한</em> 것은 아니라고 선언할 수도 있습니다. 이 경우에는, 앱이 <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#required">{@code required}</a>
+ 속성을 {@code "false"}에 설정하고 런타임을 확인하여
+해당 기기에 카메라가 있는지, 경우에 따라 모든 카메라 기능을 비활성화할 수 있는지 알아봅니다.</p>
+
+<p>여러 가지 기기와 앱의 호환성을 관리하는 방법에 대한 자세한 정보는
+<a href="{@docRoot}guide/practices/compatibility.html">기기 호환성</a>
+ 문서를 참조하십시오.</p>
+
+
+
+<h2 id="Resources">앱 리소스</h2>
+
+<p>Android 앱을 이루는 것은 코드만이 아닙니다. 소스 코드와는 별개인 여러 리소스가 필요합니다.
+예를 들어 이미지, 오디오 파일과 앱을 시각적으로 표현하는 것과 관련된 모든 것들이 있습니다.
+예컨대 애니메이션, 메뉴, 스타일, 색상과 액티비티 사용자 인터페이스의 레이아웃을 XML 파일로
+정의해야 합니다. 앱 리소스를 사용하면 앱의 다양한 특성을
+쉽게 업데이트할 수 있으며 코드를 수정하지 않아도 되고 일련의 대체 리소스를
+제공함으로써 다양한 기기 구성에 맞게 앱을
+최적화할 수도 있습니다(예: 여러 가지 언어 및 화면 크기).</p>
+
+<p>Android 프로젝트에 포함시키는 리소스마다 SDK 빌드 도구가 고유한
+정수 ID를 정의하므로, 이를 사용하여 앱 코드에서의 리소스나 XML로 정의된
+다른 리소스에서 참조할 수 있습니다. 예를 들어 앱에 {@code
+logo.png}라는 이름의 이미지 파일이 들어 있다고 하면({@code res/drawable/} 디렉터리에 저장됨) SDK 도구가
+{@code R.drawable.logo}라는 리소스 ID를 생성합니다. 이것을 사용하여 이미지를 참조하고 사용자 인터페이스에
+삽입할 수 있습니다.</p>
+
+<p>소스 코드와는 별개로 리소스를 제공하는 것의 가장 중요한 측면 중 하나는
+여러 가지 기기 구성에 맞게 대체 리소스를 제공할 능력을 갖추게
+됩니다. 예를 들어 UI 문자열을 XML로 정의하면 이러한 문자열을 다른 언어로 변환한 뒤
+그러한 문자열을 별개의 파일에 저장할 수 있습니다. 그런 다음, 리소스 디렉터리 이름에 추가한 언어 <em>한정자</em>
+(예를 들어 프랑스어 문자열 값의 경우 {@code res/values-fr/}) 및
+사용자의 언어 설정을 근거로 하여 Android 시스템이 적절한 언어 문자열을 UI에
+적용하는 것입니다.</p>
+
+<p>Android는 대체 리소스에 대해 다양한 <em>한정자</em>를 지원합니다. 한정자란
+ 리소스 디렉터리의 이름에 포함시키는 짧은 문자열로, 이를 사용해 해당 리소스를 사용할 기기 구성을
+정의합니다. 또 다른 예를 들자면,
+기기의 화면 방향과 크기에 따라 액티비티에 여러 가지 레이아웃을 생성해야 할 때가
+많습니다. 예를 들어 기기 화면이 세로
+방향(키가 큼)인 경우, 버튼이 세로 방향으로 되어 있는 레이아웃을 사용하는 것이 좋지만 화면이
+가로 방향(폭이 넓음)인 경우, 버튼이 가로 방향으로 정렬되어야 합니다. 방향에 따라 레이아웃을 변경하려면,
+서로 다른 두 가지 레이아웃을 정의하여 적절한 한정자를 각각의 레이아웃의 디렉터리 이름에
+적용하면 됩니다. 그러면 시스템이 현재 기기 방향에 따라 적절한 레이아웃을
+자동으로 적용합니다.</p>
+
+<p>애플리케이션에 포함할 수 있는 여러 가지 종류의 리소스와, 각기 다른 기기 구성에 따라
+대체 리소스를 생성하는 방법에 대한 자세한 내용은 <a href="{@docRoot}guide/topics/resources/providing-resources.html">리소스 제공</a>을 읽어보십시오.</p>
+
+
+
+<div class="next-docs">
+<div class="col-6">
+ <h2 class="norule">계속 읽기:</h2>
+ <dl>
+ <dt><a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a>
+ </dt>
+ <dd>{@link android.content.Intent} API를 사용하여
+앱 구성 요소(예: 액티비티 및 서비스 등)를 활성화하는 방법, 앱 구성 요소를 다른 여러 앱이 사용할 수 있도록 하는 방법
+등에 관한 정보입니다.</dd>
+ <dt><a href="{@docRoot}guide/components/activities.html">액티비티</a></dt>
+ <dd>{@link android.app.Activity} 클래스의 인스턴스를 생성하는 방법에 관한 정보로,
+애플리케이션에 사용자 인터페이스가 있는 독특한 화면을 제공합니다.</dd>
+ <dt><a href="{@docRoot}guide/topics/resources/providing-resources.html">리소스 제공</a></dt>
+ <dd>Android 앱이 앱 코드와는 별개의 앱 리소스에 대해 구조화된 방식에 관한 정보로,
+특정 기기 구성에 맞게 대체 리소스를 제공하는 방법도 포함되어
+있습니다.
+ </dd>
+ </dl>
+</div>
+<div class="col-6">
+ <h2 class="norule">혹시 다음과 같은 내용에도 흥미가 있으신가요?</h2>
+ <dl>
+ <dt><a href="{@docRoot}guide/practices/compatibility.html">기기 호환성</a></dt>
+ <dd>여러 가지 유형의 기기에서 Android의 작동 방식과 앱을 각 기기에 맞춰 최적화하는 방법
+또는 여러 가지 기기에 대해 앱의 가용성을 제한하는 방법 등에 관한
+정보입니다.</dd>
+ <dt><a href="{@docRoot}guide/topics/security/permissions.html">시스템 권한</a></dt>
+ <dd>Android가 특정 API에 대한 앱의 액세스를 제한하기 위해 권한 시스템을
+사용하는 방법으로, 그러한 API를 사용하려면 앱에 대해 사용자의 승인이 필요합니다.</dd>
+ </dl>
+</div>
+</div>
+
diff --git a/docs/html-intl/intl/ko/guide/components/index.jd b/docs/html-intl/intl/ko/guide/components/index.jd
new file mode 100644
index 000000000000..36626324e817
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/index.jd
@@ -0,0 +1,57 @@
+page.title=앱 구성 요소
+page.landing=true
+page.landing.intro=Android의 애플리케이션 프레임워크는 일련의 재사용 가능한 구성 요소를 사용하여 풍성하고 혁신적인 앱을 생성할 수 있습니다. 이 섹션에서는 앱의 구성 단위를 정의 내리는 구성 요소를 구축하는 방법과 인텐트를 사용하여 이와 같은 구성 요소를 연결시키는 법을 설명합니다.
+page.metaDescription=Android의 애플리케이션 프레임워크는 일련의 재사용 가능한 구성 요소를 사용하여 풍성하고 혁신적인 앱을 생성할 수 있습니다. 이 섹션에서는 앱의 구성 단위를 정의 내리는 구성 요소를 구축하는 방법과 인텐트를 사용하여 이와 같은 구성 요소를 연결시키는 법을 설명합니다.
+page.landing.image=images/develop/app_components.png
+page.image=images/develop/app_components.png
+
+@jd:body
+
+<div class="landing-docs">
+
+ <div class="col-6">
+ <h3>블로그 문서</h3>
+
+ <a href="http://android-developers.blogspot.com/2012/05/using-dialogfragments.html">
+ <h4>DialogFragment 사용하기</h4>
+ <p>이 포스트에서는 v4 지원 라이브러리와 함께 DialogFragment를 사용하여(Honeycomb 이전 기기에서 이전 버전과의 호환성을 위해) 간단한 편집 대화를 표시하고 인터페이스를 사용하여 호출 중인 액티비티에 결과를 반환하는 법을 보여드립니다.</p>
+ </a>
+
+ <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">
+ <h4>모두를 위한 프래그먼트</h4>
+ <p>Google에서는 오늘 같은 프래그먼트 API를 노출하는 정적 라이브러리를 출시했습니다(새로운 LoaderManager와 몇 가지 다른 클래스도 포함). 이 덕분에 Android 1.6 이후 버전과 호환되는 애플리케이션이 프래그먼트를 사용하여 태블릿과 호환되는 사용자 인터페이스를 생성할 수 있게 되었습니다. </p>
+ </a>
+
+ <a href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">
+ <h4>성능을 위한 다중 스레딩</h4>
+ <p>반응형 애플리케이션을 생성할 때에는 주요 UI 스레드가 최소한의 작업만
+하도록 하는 것이 좋습니다. 애플리케이션을 중단시킬 수 있는,
+길어질 수 있는 작업은 모두 다른 스레드에서 처리해야 합니다.</p>
+ </a>
+ </div>
+
+ <div class="col-6">
+ <h3>교육</h3>
+
+ <a href="http://developer.android.com/training/basics/activity-lifecycle/index.html">
+ <h4>액티비티 수명 주기 관리하기</h4>
+ <p>이 클래스에서는 각각의 액티비티
+인스턴스가 수신하는 중요한 수명 주기 콜백 메서드를 설명합니다. 또한 이러한 콜백 메서드를 사용하여 액티비티가
+사용자가 원하는 작업을 하고, 액티비티가 필요로 하지 않을 때 시스템 리소스 사용을 방지하는 방법에 대해서도 설명합니다.</p>
+ </a>
+
+ <a href="http://developer.android.com/training/basics/fragments/index.html">
+ <h4>프래그먼트로 동적 UI 구축하기</h4>
+ <p>이 클래스에서는 Android 1.6만큼 오래된 버전을 실행하는 기기도
+계속 지원하면서 프래그먼트로 동적 사용자 경험을 생성하고, 기기의 화면 크기에 따라 앱의 사용자 환경을
+최적화할 수 있는 방법을 보여줍니다.</p>
+ </a>
+
+ <a href="http://developer.android.com/training/sharing/index.html">
+ <h4>콘텐츠 공유하기</h4>
+ <p>이 클래스는 인텐트 API와 ActionProvider 객체를 사용하여 여러 애플리케이션 사이에서
+콘텐츠를 전송하고 수신하는 몇 가지 보편적인 방법을 다룹니다.</p>
+ </a>
+ </div>
+
+</div>
diff --git a/docs/html-intl/intl/ko/guide/components/intents-filters.jd b/docs/html-intl/intl/ko/guide/components/intents-filters.jd
new file mode 100644
index 000000000000..1488a1dd6472
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/intents-filters.jd
@@ -0,0 +1,899 @@
+page.title=인텐트 및 인텐트 필터
+page.tags="IntentFilter"
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Types">인텐트 유형</a></li>
+ <li><a href="#Building">인텐트 구축</a>
+ <ol>
+ <li><a href="#ExampleExplicit">명시적 인텐트 예시</a></li>
+ <li><a href="#ExampleSend">암시적 인텐트 예시</a></li>
+ <li><a href="#ForceChooser">앱 선택기 강제 적용하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#Receiving">암시적 인텐트 수신하기</a>
+ <ol>
+ <li><a href="#ExampleFilters">필터 예시</a></li>
+ </ol>
+ </li>
+ <li><a href="#PendingIntent">보류 인텐트 사용하기</a></li>
+ <li><a href="#Resolution">인텐트 확인</a>
+ <ol>
+ <li><a href="#ActionTest">작업 테스트</a></li>
+ <li><a href="#CategoryTest">카테고리 테스트</a></li>
+ <li><a href="#DataTest">데이터 테스트</a></li>
+ <li><a href="#imatch">인텐트 일치</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+<li><a href="{@docRoot}training/basics/intents/index.html">다른 앱과 상호 작용하기</a></li>
+<li><a href="{@docRoot}training/sharing/index.html">콘텐츠 공유하기</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+
+<p>{@link android.content.Intent}는 일종의 메시지 객체입니다. 이것을 사용해 다른
+<a href="{@docRoot}guide/components/fundamentals.html#Components">앱 구성 요소</a>로부터 작업을 요청할 수 있습니다.
+인텐트가 여러 구성 요소 사이의 통신을 용이하게 하는 데에는 몇 가지 방법이 있지만,
+기본적인 사용 사례는 다음과 같은 세 가지입니다.</p>
+
+<ul>
+<li><b>액티비티 시작하기:</b>
+<p>{@link android.app.Activity}는 앱 안의 화면 하나를 나타냅니다.
+{@link android.app.Activity}의 새 인스턴스를 시작하려면 {@link android.content.Intent}를
+{@link android.content.Context#startActivity startActivity()}로 전달하면 됩니다. {@link android.content.Intent}는
+시작할 액티비티를 설명하고 모든 필수 데이터를 담고 있습니다.</p>
+
+<p>액티비티가 완료되었을 때 결과를 수신하려면,
+{@link android.app.Activity#startActivityForResult
+startActivityForResult()}를 호출합니다. 액티비티는 해당 결과를 액티비티의 {@link
+android.app.Activity#onActivityResult onActivityResult()} 콜백에서 별도의
+{@link android.content.Intent} 객체로 수신합니다.
+자세한 정보는 <a href="{@docRoot}guide/components/activities.html">액티비티</a> 가이드를 참조하십시오.</p></li>
+
+<li><b>서비스 시작하기:</b>
+<p>{@link android.app.Service}는 사용자 인터페이스 없이
+배경에서 작업을 수행하는 구성 요소입니다. 서비스를 시작하여 일회성 작업을 수행하도록 하려면(예: 파일 다운로드)
+{@link android.content.Intent}를
+{@link android.content.Context#startService startService()}에 전달하면 됩니다. {@link android.content.Intent}는
+ 시작할 서비스를 설명하고 모든 필수 데이터를 담고 있습니다.</p>
+
+<p>서비스가 클라이언트-서버 인터페이스로 설계된 경우, 다른 구성 요소로부터
+서비스에 바인딩하려면 {@link android.content.Intent}를 {@link
+android.content.Context#bindService bindService()}에 전달하면 됩니다.</code> 자세한 정보는 <a href="{@docRoot}guide/components/services.html">서비스</a> 가이드를 참조하십시오.</p></li>
+
+<li><b>브로드캐스트 전달하기:</b>
+<p>브로드캐스트는 모든 앱이 수신할 수 있는 메시지입니다. 시스템은 여러 시스템 이벤트에 대해 다양한
+브로드캐스트를 전달합니다. 예를 들어 시스템이 부팅될 때 또는 기기가 변경되기 시작할 때 등이 해당됩니다.
+다른 여러 앱에 브로드캐스트를 전달하려면 {@link android.content.Intent}를
+{@link android.content.Context#sendBroadcast(Intent) sendBroadcast()},
+{@link android.content.Context#sendOrderedBroadcast(Intent, String)
+sendOrderedBroadcast()} 또는 {@link
+android.content.Context#sendStickyBroadcast sendStickyBroadcast()}에 전달하면 됩니다.</p>
+</li>
+</ul>
+
+
+
+
+<h2 id="Types">인텐트 유형</h2>
+
+<p>인텐트에는 두 가지 유형이 있습니다.</p>
+
+<ul>
+<li><b>명시적 인텐트</b>는 시작할 구성 요소를 이름으로 지정합니다(완전히
+정규화된 클래스 이름). 명시적 인텐트는 일반적으로 본인의 앱 안에서 구성 요소를 시작할 때 씁니다.
+시작하고자 하는 액티비티 또는 서비스의 클래스 이름을 알고 있기 때문입니다. 예를 들어,
+사용자 작업에 응답하여 새 액티비티를 시작하거나 배경에서 파일을 다운로드하기 위해
+서비스를 시작하는 것 등이 여기에 해당됩니다.</li>
+
+<li><b>암시적 인텐트</b>는 특정 구성 요소의 이름을 대지 않지만, 그 대신 수행할 일반적일 작업을
+선언하여 또 다른 앱의 구성 요소가 이를 처리할 수 있도록 해줍니다. 예를 들어, 사용자에게 지도에 있는 한 위치를
+표시해주고자 하는 경우, 암시적 인텐트를 사용하여 다른, 해당 기능을 갖춘 앱이
+지정된 위치를 지도에 표시하도록 요청할 수 있습니다.</li>
+</ul>
+
+<p>명시적 인텐트를 생성하여 액티비티나 서비스를 시작하도록 하면, 시스템이 즉시
+{@link android.content.Intent} 객체에서 지정된 앱 구성 요소를 시작합니다.</p>
+
+<div class="figure" style="width:446px">
+<img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 암시적 인텐트가 시스템을 통해 전달되어
+다른 액티비티를 시작하게 하는 방법을 그림으로 나타낸 것입니다. <b>[1]</b> <em>액티비티 A</em>가 작업 설명이 들어 있는
+{@link android.content.Intent}를 생성하여 이를 {@link
+android.content.Context#startActivity startActivity()}에 전달합니다. <b>[2]</b> Android 시스템이
+해당 인텐트와 일치하는 인텐트 필터를 찾아 모든 앱을 검색합니다. 일치하는 것을 찾으면, <b>[3]</b> 시스템이
+일치하는 액티비티(<em>액티비티 B</em>)를 시작하기 위해 그 액티비티의 {@link
+android.app.Activity#onCreate onCreate()} 메서드를 호출하여 이를 {@link android.content.Intent}에 전달합니다.
+</p>
+</div>
+
+<p>암시적 인텐트를 생성하면 Android 시스템이 시작시킬 적절한 구성 요소를 찾습니다.
+이때 인텐트의 내용을 기기에 있는 다른 여러 앱의 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">매니페스트 파일</a>에서 선언된 <em>인텐트 필터</em>와 비교하는 방법을
+씁니다. 해당 인텐트와 일치하는 인텐트 필터가 있으면 시스템이 해당 구성 요소를 시작하고 이에
+{@link android.content.Intent} 객체를 전달합니다. 호환되는 인텐트 필터가 여러 개인 경우, 시스템은
+대화를 표시하여 사용자가 어느 앱을 사용할지 직접 선택할 수 있게 합니다.</p>
+
+<p>인텐트 필터란 앱의 매니페스트 파일에 들어 있는 표현으로,
+해당 구성 요소가 수신하고자 하는 인텐트의 유형을
+나타낸 것입니다. 예를 들어 액티비티에 대한 인텐트 필터를 선언하면
+다른 여러 앱이 특정한 종류의 인텐트를 가지고 여러분의 액티비티를 직접 시작할 수 있습니다.
+이와 마찬가지로, 액티비티에 대한 인텐트 필터를 전혀 선언하지 <em>않으면</em> 명시적 인텐트로만
+시작할 수 있습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 앱의 보안을 보장하려면
+{@link android.app.Service}를 시작할 때에는 항상 명시적 인텐트만 사용하고 서비스에 대한 인텐트 필터는
+선언하지 마십시오. 암시적 인텐트를 사용하여 서비스를 시작하면
+보안 위험을 초래합니다. 인텐트에 어느 서비스가 응답할 것인지 확신할 수 없고, 사용자가
+어느 서비스가 시작되는지 볼 수 없기 때문입니다. Android 5.0(API 레벨 21)부터 시스템은 개발자가 암시적 인텐트로
+{@link android.content.Context#bindService bindService()}를
+호출하면 예외를 발생시킵니다.</p>
+
+
+
+
+
+<h2 id="Building">인텐트 구축</h2>
+
+<p>{@link android.content.Intent} 객체에는 Android 시스템이
+어느 구성 요소를 시작할지 판별하는 데 사용하는 정보가 담겨 있습니다(예를 들어 정확한 구성 요소 이름 또는 인텐트를
+수신해야 하는 구성 요소 카테고리 등). 또한 수신자 구성 요소가 작업을 적절히 수행하기 위해
+사용할 정보(예: 수행할 작업 및 조치를 취할 데이터 위치 등)도 이 안에 담겨 있습니다.</p>
+
+
+<p>{@link android.content.Intent} 내에 들어 있는 기본 정보는 다음과 같습니다.</p>
+
+<dl>
+
+<dt><b>구성 요소 이름</b></dt>
+<dd>시작할 구성 요소의 이름입니다.
+
+<p>이것은 선택 항목이지만, 이것이 바로 인텐트를
+<b>명시적</b>인 것으로 만들어주는 중요한 정보입니다. 다시 말해 이 인텐트는 구성 요소 이름이 정의한 앱 구성 요소에만
+전달되어야 한다는 뜻입니다. 구성 요소 이름이 없으면 해당 인텐트는 <b>암시적</b>이며,
+인텐트를 수신해야 하는 구성 요소는 다른 인텐트 정보를 기반으로 시스템이
+결정합니다(예를 들어 작업, 데이터 및 카테고리 &mdash; 아래 설명 참조). 따라서 앱에서 특정한 구성 요소를
+시작해야 하는 경우에는, 구성 요소 이름을 지정해야 합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.app.Service}를 시작하는 경우,
+<strong>항상 구성 요소 이름을 지정</strong>해야 합니다. 그렇지 않으면 인텐트에 어느 서비스가 응답할지 확신할 수 없고,
+사용자도 어느 서비스가 시작되는지 볼 수 없게 됩니다.</p>
+
+<p>{@link android.content.Intent}의 필드는
+{@link android.content.ComponentName} 객체로, 이것을 지정하려면 대상 구성 요소의 완전히
+정규화된 클래스 이름(앱의 패키지 이름 포함)을 사용해야 합니다. 예를 들면
+{@code com.example.ExampleActivity}를 쓰십시오. 구성 요소 이름을 설정하려면 {@link
+android.content.Intent#setComponent setComponent()}, {@link android.content.Intent#setClass
+setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()}을 사용하거나, 아니면
+{@link android.content.Intent} 생성자를 사용하면 됩니다.</p>
+
+</dd>
+
+<p><dt><b>작업</b></dt>
+<dd>수행할 일반적인 작업을 나타내는 문자열입니다(예: <em>보기</em> 또는 <em>선택</em>).
+
+<p>브로드캐스트 인텐트의 경우, 이것이 발생한 작업이자 보고되는 것이기도 합니다.
+인텐트의 나머지 부분이 어떻게 구조화될지는 대부분 작업이 결정합니다. 특히,
+데이터 안에 들어 있는 것과 추가 항목 등이 해당됩니다.
+
+<p>본인의 앱 내에 있는 인텐트가 사용할 작업(또는 다른 앱이 사용하여
+본인의 앱 안의 구성 요소를 호출하도록 함)을 직접 지정할 수도 있지만, 보통은
+{@link android.content.Intent} 클래스나 다른 프레임워크 클래스가 정의한 작업 상수를 써야 합니다. 다음은
+액티비티를 시작하는 데 쓰이는 보편적인 작업입니다.</p>
+
+<dl>
+<dt>{@link android.content.Intent#ACTION_VIEW}</dt>
+ <dd>이 작업은 액티비티가 사용자에게 표시할 수 있는 어떤 정보를 가지고 있을 때 {@link
+ android.content.Context#startActivity startActivity()}가 있는 인텐트에서
+사용합니다. 예를 들어 갤러리 앱에서 볼 사진이나 지도 앱에서 볼 주소 등이
+이에 해당됩니다.</dd>
+
+<dt>{@link android.content.Intent#ACTION_SEND}</dt>
+ <dd>이것은 다른 이름으로 "공유" 인텐트라고도 합니다. 이것은 사용자가 다른 앱을 통해 공유할 수 있는 데이터를 가지고 있을 때 {@link
+ android.content.Context#startActivity startActivity()}가 있는 인텐트에서 사용합니다. 예를 들어
+이메일 앱 또는 소셜 공유 앱 등이 이에 해당됩니다.</dd>
+</dl>
+
+<p>일반적인 작업을 정의하는 상수에 대한 자세한 내용은 {@link android.content.Intent} 클래스
+참조를 확인하십시오. 다른 작업은 Android 프레임워크의 다른 곳에서 정의됩니다. 예를 들어
+시스템의 설정 앱에서 특정 화면을 여는 작업의 경우 {@link android.provider.Settings}에서
+정의됩니다.</p>
+
+<p>인텐트에 대한 작업을 지정하려면 {@link android.content.Intent#setAction
+setAction()} 또는 {@link android.content.Intent} 생성자를 사용하면 됩니다.</p>
+
+<p>나름의 작업을 직접 정의하는 경우, 앱의 패키지 이름을 접두사로 포함시켜야
+합니다. 예:</p>
+<pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre>
+</dd>
+
+<dt><b>데이터</b></dt>
+<dd>작업을 수행할 데이터 및/또는 해당 데이터의 MIME 유형을 참조하는 URI({@link android.net.Uri}
+객체)입니다. 제공된 데이터의 유형을 나타내는 것은 일반적으로 인텐트의 작업입니다. 예를 들어
+인텐트가 {@link android.content.Intent#ACTION_EDIT}인 경우, 데이터에
+편집할 문서의 URI가 들어있어야 합니다.
+
+<p>인텐트를 생성할 때에는
+URI외에도 데이터의 유형(MIME 유형)을 지정하는 것이 중요한 경우가 많습니다.
+예를 들어, 이미지를 표시할 수 있는 액티비티는 아마도 오디오 파일을 재생할 수 없을 가능성이
+큽니다. 두 가지 기능의 URI 형식은 비슷할지라도 말입니다.
+그러므로 데이터의 MIME 유형을 지정해두면 Android 시스템이
+인텐트를 수신할 최상의 구성 요소를 찾는 데 도움이 됩니다.
+하지만, MIME 유형은 URI에서 추론되는 경우도 종종 있습니다. 특히 데이터가
+{@code content:} URI인 경우 더욱 그러한데, 이는 데이터가 기기에 위치하고 있으며
+{@link android.content.ContentProvider}가 제어한다는 것을 나타내어 해당 데이터 MIME 유형이 시스템에 표시되도록 합니다.</p>
+
+<p>데이터 URI만 설정하려면 {@link android.content.Intent#setData setData()}를 호출하십시오.
+MIME 유형만 설정하려면, {@link android.content.Intent#setType setType()}을 호출합니다. 필요한 경우,
+두 가지를 모두 명시적으로 설정해도 됩니다. 이때는 {@link
+android.content.Intent#setDataAndType setDataAndType()}을 사용하십시오.</p>
+
+<p class="caution"><strong>주의:</strong> URI와 MIME 유형을 둘 다 설정하고자 하는 경우, {@link android.content.Intent#setData setData()} 및
+{@link android.content.Intent#setType setType()}을 호출하면
+<strong>안 됩니다</strong>. 이 둘은 서로의 값을 무효화하기 때문입니다. URI와 MIME 유형을 둘 모두 설정하려면
+항상 {@link android.content.Intent#setDataAndType setDataAndType()}을
+사용하십시오.</p>
+</dd>
+
+<p><dt><b>카테고리</b></dt>
+<dd>인텐트를 처리해야 하는 구성 요소의 종류에 관한 추가 정보를 담은
+문자열입니다. 인텐트 안에는 카테고리 설명이
+얼마든지 들어있을 수 있지만, 대부분의 인텐트에는 카테고리가 없어도 됩니다.
+다음은 몇 가지 보편적인 카테고리입니다.
+
+<dl>
+<dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt>
+ <dd>대상 액티비티가 스스로 웹 브라우저가 자신을 시작해도 되도록 허용하여
+링크로 참조된 데이터를 표시하게 합니다. 예컨대 이미지나 이메일 메시지 등이 이에 해당합니다.
+ </dd>
+<dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt>
+ <dd>이 액티비티가 작업의 최초 액티비티이며, 이것이 시스템의 애플리케이션 시작 관리자에
+목록으로 게재되어 있습니다.
+ </dd>
+</dl>
+
+<p>카테고리의 전체 목록을 보려면 {@link android.content.Intent}
+클래스 설명을 참조하십시오.</p>
+
+<p>카테고리를 지정하려면 {@link android.content.Intent#addCategory addCategory()}를 사용하면 됩니다.</p>
+</dd>
+</dl>
+
+
+<p>위에 목록으로 나열된 이러한 특성(구성 요소 이름, 작업, 데이터 및 카테고리)은 인텐트를 정의하는 특성을
+나타냅니다. Android 시스템은 이와 같은 속성을 읽어
+어느 앱 구성 요소를 시작해야 할지 확인할 수 있습니다.</p>
+
+<p>그러나 인텐트는 앱 구성 요소로 확인되는 방법에 영향을 미치지 않는
+추가 정보도 담고 있을 수 있습니다. 인텐트가 제공할 수 있는 기타 정보는 다음과 같습니다.</p>
+
+<dl>
+<dt><b>추가 사항</b></dt>
+<dd>요청한 작업을 수행하기 위해 필요한 추가 정보를 담고 있는 키-값 쌍입니다.
+몇몇 작업이 특정한 종류의 데이터 URI를 사용하는 것과 마찬가지로, 몇몇 작업은 특정한 추가 사항도 사용합니다.
+
+<p>추가 데이터를 추가하려면 여러 가지 {@link android.content.Intent#putExtra putExtra()} 메서드를
+사용할 수 있습니다. 이들은 각기 두 개의 매개변수를 허용합니다. 즉 키 이름과 값입니다.
+모든 추가 데이터를 가진 {@link android.os.Bundle} 객체를 생성할 수도 있고, 그런 다음
+{@link android.os.Bundle}을 {@link android.content.Intent}에 {@link
+android.content.Intent#putExtras putExtras()}로 삽입해도 됩니다.</p>
+
+<p>예를 들어
+{@link android.content.Intent#ACTION_SEND}로 이메일을 전송할 인텐트를 생성하는 경우 "받는 사람" 수신자를 지정할 때
+{@link android.content.Intent#EXTRA_EMAIL} 키를 사용한 다음 "제목"은
+{@link android.content.Intent#EXTRA_SUBJECT} 키로 지정하면 됩니다.</p>
+
+<p>{@link android.content.Intent} 클래스는 표준화된 데이터 유형에 대해 수많은 {@code EXTRA_*} 상수를
+지정합니다. 나름의 추가 키를 선언해야 하는 경우(본인의 앱이 수신할
+인텐트에 대하여), 앱의 패키지 이름을 접두사로 포함시커야
+합니다. 예:</p>
+<pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre>
+</dd>
+
+<dt><b>플래그</b></dt>
+<dd>{@link android.content.Intent} 클래스에서 정의된 플래그로, 인텐트에 대한 메타데이터와 같은 기능을
+합니다. 이런 플래그는 Android 시스템에 액티비티를 시작할 방법에 대한 지침을 줄 수도 있고(예를 들어 액티비티가 어느
+<a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업</a>에 소속되어야 하는지 등)
+ 액티비티를 시작한 다음에 어떻게 처리해야 하는지도 알려줄 수 있습니다(예를 들어 해당 액티비티가 최근
+액티비티 목록에 소속되는지 여부).
+
+<p>자세한 정보는 {@link android.content.Intent#setFlags setFlags()} 메서드를 참조하십시오.</p>
+</dd>
+
+</dl>
+
+
+
+
+<h3 id="ExampleExplicit">명시적 인텐트 예시</h3>
+
+<p>명시적 인텐트는 특정한 앱 구성 요소를 시작하기 위해 사용하는 것입니다. 예를 들어 앱 내의
+특정 액티비티나 서비스를 말합니다. 명시적 인텐트를 생성하려면
+{@link android.content.Intent} 객체에 대한 구성 요소 이름을 정의합니다. 다른
+인텐트 속성은 모두 선택 사항입니다.</p>
+
+<p>예를 들어 앱 안에 {@code DownloadService}라는 서비스를 구축했다고 합시다.
+이 서비스는 웹 상에서 파일을 다운로드하도록 설계된 것입니다. 이것을 시작하려면 다음과 같은 코드를 사용하면 됩니다.</p>
+
+<pre>
+// Executed in an Activity, so 'this' is the {@link android.content.Context}
+// The fileUrl is a string URL, such as "http://www.example.com/image.png"
+Intent downloadIntent = new Intent(this, DownloadService.class);
+downloadIntent.setData({@link android.net.Uri#parse Uri.parse}(fileUrl));
+startService(downloadIntent);
+</pre>
+
+<p>{@link android.content.Intent#Intent(Context,Class)}
+ 생성자가 앱에 {@link android.content.Context}를 제공하고
+구성 요소에 {@link java.lang.Class} 객체를 제공합니다. 이처럼,
+이 인텐트는 앱 내의 {@code DownloadService} 클래스를 명시적으로 시작합니다.</p>
+
+<p>서비스를 구축하고 시작하는 데 대한 자세한 정보는
+<a href="{@docRoot}guide/components/services.html">서비스</a> 가이드를 참조하십시오.</p>
+
+
+
+
+<h3 id="ExampleSend">암시적 인텐트 예시</h3>
+
+<p>암시적 인텐트는 작업을 지정하여 기기에서 해당 작업을 수행할 수 있는 모든 앱을 호출할 수
+있도록 합니다. 암시적 인텐트를 사용하면 본인의 앱은 작업을 수행할 수 없지만 다른 앱은 아마도 할 수 있을 때,
+그리고 사용자로 하여금 어느 앱을 사용할지 선택하도록 하고자 할 때 유용합니다.</p>
+
+<p>예를 들어 사용자가 다른 사람들과 공유했으면 하는 콘텐츠를 가지고 있는 경우,
+{@link android.content.Intent#ACTION_SEND} 작업이 있는 인텐트를 생성한 다음
+공유할 콘텐츠를 지정하는 추가 정보를 추가하면 됩니다. 해당 인텐트로
+{@link android.content.Context#startActivity startActivity()}를 호출하면
+사용자가 어느 앱을 통해 콘텐츠를 공유할지 선택할 수 있습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 개발자가 {@link android.content.Context#startActivity
+startActivity()}로 전송한 암시적 인텐트를 처리할 앱이 사용자에게 <em>전혀</em>
+표시되지 않을 수도 있습니다. 이런 일이 발생하면, 호출이 실패하고 앱 작동이 중단됩니다. 어느 액티비티든
+이 인텐트를 수신하도록 확실히 하려면, {@link android.content.Intent} 객체의 {@link android.content.Intent#resolveActivity
+resolveActivity()}를 호출합니다. 결과가 null이 아닌 경우,
+인텐트를 처리할 수 있는 앱이 최소한 하나는 있다는 뜻이며
+{@link android.content.Context#startActivity startActivity()}를 호출해도 안전합니다. 결과가 null이면,
+해당 인텐트를 사용해서는 안 되며 가능한 경우 해당 인텐트를 발생시키는 기능을 비활성화해야
+합니다.</p>
+
+
+<pre>
+// Create the text message with a string
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
+sendIntent.setType("text/plain");
+
+// Verify that the intent will resolve to an activity
+if (sendIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(sendIntent);
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> 이 경우에서는 URI를 사용하지 않았지만 인텐트의 데이터 유형이 정의되어
+추가 정보가 담고 있는 콘텐츠를 지정하였습니다.</p>
+
+
+<p>{@link android.content.Context#startActivity startActivity()}를 호출하면 시스템이
+설치된 앱을 모두 살펴보고 이런 종류의 인텐트를 처리할 수 있는 앱이 어느 것인지 알아봅니다(
+{@link android.content.Intent#ACTION_SEND} 작업이 있는 인텐트이며 "텍스트/일반"
+데이터가 담긴 것). 이것을 처리할 수 있는 앱이 하나뿐이면, 해당 앱이 즉시 열리고 이 앱에 인텐트가
+주어집니다. 인텐트를 허용하는 액티비티가 여러 개인 경우, 시스템은
+대화를 표시하여 사용자가 어느 앱을 사용할지 직접 선택할 수 있게 합니다.</p>
+
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="">
+ <p class="img-caption"><strong>그림 2.</strong> 선택기 대화입니다.</p>
+</div>
+
+<h3 id="ForceChooser">앱 선택기 강제 적용하기</h3>
+
+<p>암시적 인텐트에 응답하는 앱이 하나 이상인 경우,
+사용자가 어느 앱을 사용할지 선택할 수 있으며 해당 앱을 이 작업에 대한 기본 선택으로 만들 수
+있습니다. 이는 사용자가 이제부터 계속 같은 앱을 사용하고자 할 것이라고 추정되는 작업을
+수행할 때 좋습니다. 예를 들어 웹 페이지를 열 때가 이에 해당됩니다(대다수 사용자가
+웹 브라우저는 하나만 사용하는 것을 선호합니다).</p>
+
+<p>그러나, 인텐트에 응답할 수 있는 앱이 여러 개이고 사용자가 매번 다른 앱을 사용하기를 원할 수도 있는
+경우라면, 선택기 대화를 명시적으로 표시해야 합니다. 선택기 대화 상자는
+사용자가 작업에 사용할 앱을 매번 선택하도록 물어봅니다(사용자는 작업에 사용할
+기본 앱을 선택할 수 없습니다). 예를 들어 앱이 {@link
+android.content.Intent#ACTION_SEND} 작업에 "공유"를 수행하는 경우, 사용자는 각자의 현재 상황에 따라 여러 가지 다른 앱을 사용하여 공유하기를
+원할 수도 있습니다. 따라서 항상 선택기 대화를 사용해야 합니다(그림 2 참조).</p>
+
+
+
+
+<p>선택기를 표시하려면 {@link
+android.content.Intent#createChooser createChooser()}를 사용하여 {@link android.content.Intent}를 생성한 후 {@link
+android.app.Activity#startActivity startActivity()}에 전달합니다. 예:</p>
+
+<pre>
+Intent sendIntent = new Intent(Intent.ACTION_SEND);
+...
+
+// Always use string resources for UI text.
+// This says something like "Share this photo with"
+String title = getResources().getString(R.string.chooser_title);
+// Create intent to show the chooser dialog
+Intent chooser = Intent.createChooser(sendIntent, title);
+
+// Verify the original intent will resolve to at least one activity
+if (sendIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>이 예시는 {@link
+android.content.Intent#createChooser createChooser()} 메서드에 전달된 인텐트에 응답하는 앱 목록이 포함된 대화 상자를 표시하고 제공된 텍스트를
+대화 상자 제목으로 사용합니다.</p>
+
+
+
+
+
+
+
+
+
+<h2 id="Receiving">암시적 인텐트 수신하기</h2>
+
+<p>본인의 앱이 수신할 수 있는 암시적 인텐트가 어느 것인지 알리려면,
+각 앱 구성 요소에 대한 하나 이상의 인텐트 필터를 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+ 요소로 <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">매니페스트 파일</a>에 선언합니다.
+각 인텐트 필터가 인텐트의 작업, 데이터 및 카테고리를 근거로 어느 유형의 인텐트를
+허용하는지 나타냅니다. 시스템이 앱 구성 요소에 암시적 인텐트를 전달하는 것은 인텐트가 개발자의 인텐트 필터 중 하나를
+통과해 지나갈 수 있는 경우뿐입니다.</p>
+
+<p class="note"><strong>참고:</strong> 명시적 인텐트는 항상 자신의 대상에 전달되며,
+이는 구성 요소가 어떤 인텐트 필터를 선언하든 무관합니다.</p>
+
+<p>앱 구성 요소는 자신이 수행할 수 있는 각 고유한 작업에 대해 별도의 필터를 선언해야 합니다.
+예를 들어 이미지 갤러리 앱에 있는 한 액티비티에 두 개의 필터가 있을 수 있습니다. 필터 하나는
+이미지를 보고, 또 다른 필터는 이미지를 편집하는 것입니다. 액티비티가 시작되면, 이는
+{@link android.content.Intent}를 검사한 다음
+{@link android.content.Intent}에 있는 정보를 근거로 어떻게 동작할 것인지 결정합니다(편집기 제어 항목을 표시할 것인지 말 것인지 등).</p>
+
+<p>각 인텐트 필터는 앱의 매니페스트 파일에 있는 <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+요소가 정의하며, 이는 상응하는 앱 구성 요소에 중첩되어
+있습니다(예: <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+요소). <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a> 내부에서는
+다음과 같은 세 가지 요소 중 하나 이상을 사용하여 허용할 인텐트 유형을 지정할 수
+있습니다.</p>
+
+<dl>
+<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a></dt>
+ <dd>허용된 인텐트 작업을 {@code name} 속성에서 선언합니다. 이 값은
+어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.</dd>
+<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a></dt>
+ <dd>허용된 데이터 유형을 선언합니다. 이때
+데이터 URI(<code>scheme</code>, <code>host</code>, <code>port</code>,
+<code>path</code> 등)와 MIME 유형의 여러 가지 측면을 나타내는 하나 이상의 속성을 사용하는 방법을 씁니다.</dd>
+<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a></dt>
+ <dd>허용된 인텐트 카테고리를 {@code name} 속성에서 선언합니다. 이 값은
+어떤 작업의 리터럴 문자열 값이어야 하며, 클래스 상수가 아닙니다.
+
+ <p class="note"><strong>참고:</strong> 암시적 인텐트를 수신하려면 인텐트 필터 안에
+
+{@link android.content.Intent#CATEGORY_DEFAULT} 카테고리를 <strong>반드시 포함</strong>해야 합니다.
+{@link android.app.Activity#startActivity startActivity()} 및
+{@link android.app.Activity#startActivityForResult startActivityForResult()} 메서드는
+모든 인텐트를 마치 {@link android.content.Intent#CATEGORY_DEFAULT} 카테고리를 선언한 것처럼 취급합니다.
+ 이 카테고리를 인텐트 필터에서 선언하지 않으면 액티비티에 어떤 암시적 인텐트도
+확인되지 않습니다.</p>
+ </dd>
+</dl>
+
+<p>예를 들어, 다음은 데이터 유형이 텍스트인 경우
+{@link android.content.Intent#ACTION_SEND} 인텐트를 수신할 인텐트 필터가 있는 액티비티 선언입니다.</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a>,
+<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 또는
+<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>의 인스턴스가 하나 이상 포함된 필터를 생성해도 됩니다.
+그렇게 하는 경우, 그저 해당 구성 요소가 그와 같은 필터 요소의 모든 조합을 처리할 수 있도록
+확실히 하기만 하면 됩니다.</p>
+
+<p>여러 가지 종류의 인텐트를 처리하고자 하되 특정 조합의 작업, 데이터 및 카테고리 유형으로만 한정하고자 한다면
+여러 가지 인텐트 필터를 생성해야 합니다.</p>
+
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>구성 요소로의 액세스 제한</h2>
+<p>인텐트 필터를 사용하는 것은 다른 앱이 여러분의 구성 요소를 시작하지 못하도록 방지하기에
+안전한 방식은 아닙니다. 인텐트 필터는 구성 요소로 하여금 특정한 종류의 암시적 인텐트에만
+응답하도록 제한하기는 하지만, 다른 앱이 여러분의 앱 구성 요소를 시작할 가능성도 있습니다.
+해당 개발자가 여러분의 구성 요소 이름을 알아내는 경우 명시적 인텐트를 사용하면 됩니다.
+구성 요소 중 하나를 시작하는 것은 <em>오직 본인 소유의 앱</em>으로 한정하는 것이 중요한 경우, 해당 구성 요소에 대하여
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#exported">{@code
+exported}</a> 속성을 {@code "false"}로 설정하십시오.
+</p>
+</div>
+</div>
+
+<p>암시적 인텐트를 필터에 대해 테스트하려면 인텐트를 세 가지 요소에 대해 각기
+비교합니다. 인텐트가 구성 요소에 전달되려면 해당 인텐트는 세 개의 테스트를 모두 통과해야 합니다.
+하나라도 일치하지 못하고 실패하면 Android 시스템이 해당 인텐트를 구성 요소에 전달하지
+않습니다. 그러나 구성 요소에는 여러 개의 인텐트 필터가 있을 수도 있으므로, 구성 요소의
+필터 중 하나를 통과하지 않는 인텐트도 다른 필터를 통하면 성공할 수 있습니다.
+시스템이 인텐트를 확인하는 방법에 대한 자세한 정보는
+<a href="#Resolution">인텐트 확인</a>에 대해 다룬 아래 섹션에 제공되어 있습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 부주의로 다른 앱의
+{@link android.app.Service}를 실행하는 일을 피하려면, 항상 명시적 인텐트를 사용하여 본인의 서비스를 시작하고 서비스에 대한
+인텐트 필터는 선언하지 마십시오.</p>
+
+<p class="note"><strong>참고:</strong>
+액티비티 전체에 대해 인텐트 필터를 매니페스트 파일에서 선언해야 합니다.
+다만 브로드캐스트 수신기에 대한 필터의 경우 동적으로 등록할 수도 있습니다.
+{@link android.content.Context#registerReceiver(BroadcastReceiver, IntentFilter, String,
+Handler) registerReceiver()}를 호출하면 됩니다. 그런 다음 해당 수신기를 등록 해제하려면 {@link
+android.content.Context#unregisterReceiver unregisterReceiver()}를 사용하십시오. 이렇게 하면 앱이
+실행되는 동안에 정해진 기간 동안 특정한 브로드캐스트에 대해 수신 대기할 수
+있습니다.</p>
+
+
+
+
+
+
+
+<h3 id="ExampleFilters">필터 예시</h3>
+
+<p>몇 가지 인텐트 필터 동작에 대해 이해를 돕기 위해 소셜 공유 앱의 매니페스트 파일에서
+가져온 다음 조각을 참조하십시오.</p>
+
+<pre>
+&lt;activity android:name="MainActivity">
+ &lt;!-- This activity is the main entry, should appear in app launcher -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+
+&lt;activity android:name="ShareActivity">
+ &lt;!-- This activity handles "SEND" actions with text data -->
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter&gt;
+ &lt;!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;action android:name="android.intent.action.SEND_MULTIPLE"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="application/vnd.google.panorama360+jpg"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="video/*"/>
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p>첫 번째 액티비티인 {@code MainActivity}는 앱의 주요 진입 지점입니다. 즉 이것이
+사용자가 시작 관리자 아이콘을 사용하여 앱을 처음 시작할 때 열리는 액티비티입니다.</p>
+<ul>
+ <li>{@link android.content.Intent#ACTION_MAIN} 작업은
+이것이 주요 진입 지점이며 어느 인텐트 데이터도 기대하지 않는다는 것을 나타냅니다.</li>
+ <li>{@link android.content.Intent#CATEGORY_LAUNCHER} 카테고리는
+이 액티비티의 아이콘이 시스템의 앱 시작 관리자에 배치되어야 한다는 것을 나타냅니다. <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> 요소가
+아이콘을 {@code icon}으로 지정하지 않은 경우, 시스템은 <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+ 요소로부터 가져온 아이콘을 사용합니다.</li>
+</ul>
+<p>이들 두 가지가 함께 페어링되어야 액티비티가 앱 시작 관리자에 나타날 수 있습니다.</p>
+
+<p>두 번째 액티비티인 {@code ShareActivity}는 텍스트와 미디어 콘텐츠 공유를
+용이하게 할 목적으로 만들어진 것입니다. 사용자가 {@code MainActivity}에서 이 액티비티를 향해 이동하다가 이 안에 진입할 수도 있지만,
+두 가지 인텐트 필터 중 하나와 일치하는 암시적 인텐트를 발생시키는 또 다른 앱에서 {@code ShareActivity}에 직접 진입할 수도
+있습니다.</p>
+
+<p class="note"><strong>참고:</strong> MIME 유형, 즉
+<a href="https://developers.google.com/panorama/android/">{@code
+application/vnd.google.panorama360+jpg}</a>는 파노라마 사진을 나타내는
+특수 데이터 유형으로, 이것은 <a href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google
+파노라마</a> API로 처리할 수 있습니다.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h2 id="PendingIntent">보류 인텐트 사용하기</h2>
+
+<p>{@link android.app.PendingIntent} 객체는 {@link
+android.content.Intent} 객체 주변을 감싸는 래퍼입니다. {@link android.app.PendingIntent}의
+기본 목적은 외래 애플리케이션에 권한을 허가하여 안에 들어 있는
+{@link android.content.Intent}를
+마치 본인 앱의 자체 프로세스에서 실행하는 것처럼 사용하게 하는 것입니다.</p>
+
+<p>보류 인텐트의 주요 사용 사례는 다음과 같습니다.</p>
+<ul>
+ <li>사용자가 여러분의 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">알림</a>으로
+작업을 수행할 때 인텐트가 실행되도록 선언합니다(Android 시스템의 {@link android.app.NotificationManager}가
+{@link android.content.Intent}를 실행합니다).
+ <li>사용자가 여러분의
+<a href="{@docRoot}guide/topics/appwidgets/index.html">앱 위젯</a>으로
+작업을 수행할 때 인텐트가 실행되도록 선언합니다(메인 스크린 앱이 {@link android.content.Intent}를 실행합니다).
+ <li>향후 지정된 시간에 인텐트가 실행되도록 선언합니다(Android
+시스템의 {@link android.app.AlarmManager}가 {@link android.content.Intent}를 실행합니다).
+</ul>
+
+<p>각 {@link android.content.Intent} 객체는 특정한 유형의
+앱 구성 요소가({@link android.app.Activity}, {@link android.app.Service} 또는
+{@link android.content.BroadcastReceiver}) 처리하도록 설계되어 있기 때문에, {@link android.app.PendingIntent}도
+같은 고려 사항을 염두에 두고 생성해야 합니다. 보류 인텐트를 사용하는 경우, 여러분의 앱은
+{@link android.content.Context#startActivity
+startActivity()}와 같은 호출이 있는 앱을 실행하지 않게 됩니다. 대신
+{@link android.app.PendingIntent}를 생성할 때 원래 의도한 구성 요소 유형을 선언해야 합니다. 이때 각각의 생성자 메서드를 호출하는 방법을 씁니다.</p>
+
+<ul>
+ <li>{@link android.app.Activity}를 시작하는 {@link android.content.Intent}의 경우,
+{@link android.app.PendingIntent#getActivity PendingIntent.getActivity()}</li>
+ <li>{@link android.app.Service}를 시작하는 {@link android.content.Intent}의 경우,
+{@link android.app.PendingIntent#getService PendingIntent.getService()}</li>
+ <li>{@link android.content.BroadcastReceiver}를 시작하는 {@link android.content.Intent}의 경우,
+{@link android.app.PendingIntent#getBroadcast PendingIntent.getBroadcast()}</li>
+</ul>
+
+<p>여러분의 앱이 다른 여러 앱에서 보류 인텐트를 <em>수신</em>하는 것이 아닌 한,
+위의 메서드를 사용하여 {@link android.app.PendingIntent}를 생성하는 것이 아마도 여러분에게 필요한 유일한
+{@link android.app.PendingIntent} 메서드일 것입니다.</p>
+
+<p>각 메서드는 현재 앱의 {@link android.content.Context}, 래핑하고자 하는
+{@link android.content.Intent}와 인텐트의 적절한 사용 방식을 나타내는
+ 하나 이상의 플래그(인텐트를 한 번 이상 사용할 수 있는지 등) 등을 취합니다.</p>
+
+<p>보류 인텐트 사용에 관한 자세한 정보는 각 해당되는 사용 사례에 대한 문서에
+제공되어 있습니다. 예를 들어 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">알림</a>
+ 및 <a href="{@docRoot}guide/topics/appwidgets/index.html">앱 위젯</a> API 가이드가 이에 해당됩니다.</p>
+
+
+
+
+
+
+
+<h2 id="Resolution">인텐트 확인</h2>
+
+
+<p>시스템이 액티비티를 시작하라는 암시적 인텐트를 수신하면, 시스템은 해당 인텐트에 대한 최선의 액티비티를 검색합니다.
+이때 다음과 같은 세 가지 측면을 근거로 인텐트를 인텐트 필터에 비교해 보는 방법을 씁니다.</p>
+
+<ul>
+ <li>인텐트 작업
+ <li>인텐트 데이터(URI와 데이터 유형 둘 다)
+ <li>인텐트 카테고리
+</ul>
+
+<p>다음 섹션에서는 인텐트 필터가 앱의 매니페스트 파일에서 어떻게 선언되었는지와 관련하여
+인텐트가 적절한 구성 요소에 일치되는 방식을 설명합니다.</p>
+
+
+<h3 id="ActionTest">작업 테스트</h3>
+
+<p>허용된 인텐트 작업을 나타내려면 인텐트 필터는 0개 이상의
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> 요소를 선언할 수 있습니다. 예:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.EDIT" /&gt;
+ &lt;action android:name="android.intent.action.VIEW" /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>이 필터를 통과하려면 {@link android.content.Intent}에
+지정된 작업이 필터에 목록으로 나열된 작업 중 하나와 일치해야만 합니다.</p>
+
+<p>필터에 목록으로 나열된 작업이 없는 경우, 인텐트가 일치될 대상이 아무것도 없으므로
+모든 인텐트가 테스트에 실패합니다. 그러나, {@link android.content.Intent}가
+작업을 지정하지 않는 경우, 테스트를 통과하게 됩니다(필터에 최소한 한 개 이상의 작업이
+들어있지 않은 한).</p>
+
+
+
+<h3 id="CategoryTest">카테고리 테스트</h3>
+
+<p>허용된 인텐트 카테고리를 나타내려면 인텐트 필터는 0개 이상의
+<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> 요소를 선언할 수 있습니다. 예:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;category android:name="android.intent.category.DEFAULT" /&gt;
+ &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>인텐트가 카테고리 테스트를 통과하려면 {@link android.content.Intent} 내의
+모든 카테고리가 필터 내의 카테고리에 일치해야 합니다. 이 반대로는 반드시 성립하지 않아도 됩니다. 인텐트 필터가
+{@link android.content.Intent}에서 지정된 것보다 더 많은 카테고리를 선언할 수도 있지만 그래도
+{@link android.content.Intent}는 통과합니다. 그러므로, 카테고리가 없는 인텐트라면 이 테스트를 항상 통과하는 것이 맞습니다.
+이는 필터에 어떤 카테고리가 선언되어 있는지와는 무관합니다.</p>
+
+<p class="note"><strong>참고:</strong>
+Android는 {@link android.content.Intent#CATEGORY_DEFAULT} 카테고리를
+{@link
+android.content.Context#startActivity startActivity()} 및 {@link
+android.app.Activity#startActivityForResult startActivityForResult()}에 전달된 모든 암시적 인텐트에 적용합니다.
+따라서 액티비티가 암시적 인텐트를 수신하기를 원하는 경우,
+그 인텐트 필터 내에 {@code "android.intent.category.DEFAULT"}에 대한 카테고리가 반드시 포함되어 있어야 합니다(이전의
+{@code &lt;intent-filter&gt;} 예시에서 표시된 내용 참조).</p>
+
+
+
+<h3 id="DataTest">데이터 테스트</h3>
+
+<p>허용된 인텐트 데이터를 나타내려면 인텐트 필터는 0개 이상의
+<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> 요소를 선언할 수 있습니다. 예:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:mimeType="video/mpeg" android:scheme="http" ... /&gt;
+ &lt;data android:mimeType="audio/mpeg" android:scheme="http" ... /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>각 <code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
+요소는 URI 구조와 데이터 유형(MIME 미디어 유형)을 나타낼 수 있습니다. URI의 각 부분에 대해 별도의
+속성&mdash;{@code scheme}, {@code host}, {@code port}
+및 {@code path}&mdash;이 있습니다.
+</p>
+
+<p style="margin-left: 2em">{@code &lt;scheme&gt;://&lt;host&gt;:&lt;port&gt;/&lt;path&gt;}</p>
+
+<p>
+예:
+</p>
+
+<p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p>
+
+<p>이 URI에서 구성표는 {@code content}이고 호스트는 {@code com.example.project},
+포트는 {@code 200}이며 경로는 {@code folder/subfolder/etc}입니다.
+</p>
+
+<p>이와 같은 속성은 각각 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 요소에서 선택 항목이지만,
+이들 사이에 선형적 종속 관계가 있습니다.</p>
+<ul>
+ <li>구성표가 지정되지 않으면 호스트가 무시됩니다.</li>
+ <li>호스트가 지정되지 않으면 포트가 무시됩니다.</li>
+ <li>구성표와 호스트가 둘 다 지정되지 않으면 경로가 무시됩니다.</li>
+</ul>
+
+<p>인텐트 안의 URI가 필터 안의 URI 사양에 비교되는 경우, 이것은 필터 내에 포함된 URI의
+몇몇 부분에만 비교되는 것입니다. 예:</p>
+<ul>
+ <li>필터가 구성표만 지정하는 경우, 해당 구성표가 있는 모든 URI가 필터와
+일치합니다.</li>
+ <li>필터가 구성표와 권한은 지정하지만 경로는 지정하지 않는 경우, 같은 구성표와 권한이 있는
+모든 URI가 경로와 관계 없이 필터를 통과합니다.</li>
+ <li>필터가 구성표, 권한과 경로를 지정하는 경우 같은 구성표,
+권한과 경로가 있는 URI만 해당 필터를 통과합니다.</li>
+</ul>
+
+<p class="note"><strong>참고:</strong> 경로 사양에는 경로 이름이
+부분적으로만 일치하도록 요구하기 위해 와일드카드 별표(*)가 들어 있을 수 있습니다.</p>
+
+<p>데이터 테스트는 인텐트 안의 URI와 MIME 유형 둘 모두를 필터 안에서
+지정된 MIME 유형과 비교합니다. 규칙은 다음과 같습니다.
+</p>
+
+<ol type="a">
+<li>URI도 MIME 유형도 들어 있지 않은 인텐트가 테스트를 통과하는 것은
+필터가 URI나 MIME 유형을 전혀 지정하지 않은 경우뿐입니다.</li>
+
+<li>URI는 들어 있지만 MIME 유형은 없는 인텐트(URI로부터는
+명시적이지도 않고 추론할 수도 없음)가 테스트를 통과하는 것은 그 URI가 필터의 URI 형식과 일치하며
+필터가 인텐트와 마찬가지로 MIME 유형을 지정하지 않는 경우뿐입니다.</li>
+
+<li>MIME 유형은 들어 있지만 URI는 없는 인텐트가 테스트를 통과하는 것은
+해당 필터가 같은 MIME 유형을 목록으로 나열하지만 URI 형식은 지정하지 않은 경우뿐입니다.</li>
+
+<li>URI와 MIME 유형이 둘 다 들어 있는 인텐트(URI로부터는
+명시적이지도 않고 추론할 수도 없음)가 테스트의 MIME 유형 부분을 통과하는 것은 해당 유형이
+필터 내에 목록으로 나열된 한 유형에 일치하는 경우뿐입니다. 이것이 테스트의 URI 부분을 통과하는 것은
+URI가 필터 내의 URI와 일치하거나, {@code content:}
+ 또는 {@code file:} URI가 있고 필터가 URI를 지정하지 않은 경우뿐입니다. 달리 말하면,
+구성 요소는 필터가 MIME 유형 <em>하나만</em> 목록으로 나열하는 경우 {@code content:} 및 {@code file:} 데이터를
+지원하는 것으로 간주한다는 뜻입니다.</p></li>
+</ol>
+
+<p>
+마지막 규칙인 규칙 (d)는
+구성 요소가 파일이나 콘텐츠 제공자로부터 로컬 파일을 가져올 수 있는지에 대한 기대 수준을 반영합니다.
+따라서 이러한 필터는 데이터 유형만 목록으로 나열해도 되고,
+{@code content:} 및 {@code file:} 구성표의 이름을 명시적으로 제시하지 않아도 됩니다.
+이것이 일반적인 경우입니다. 예를 들어, 다음 예시와 같은 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> 요소는
+Android에 구성 요소가 콘텐츠 제공자에서 이미지 데이터를 가져와 표시할 수 있다고
+알립니다.
+</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:mimeType="image/*" /&gt;
+ ...
+&lt;/intent-filter&gt;</pre>
+
+<p>
+대부분의 사용 가능한 데이터는 콘텐츠 제공자가 제공하는 것이므로, 데이터 유형은
+지정하지만 URI는 지정하지 않는 필터가 아마 가장 보편적인 유형일 것입니다.
+</p>
+
+<p>
+또 다른 보편적인 구성을 예로 들자면 구성표와 데이터 유형을 가진 필터가 있겠습니다. 예를 들어
+다음 예시와 같은 <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>
+ 요소는 Android에 구성 요소가
+작업을 수행하기 위해 네트워크에서 비디오 데이터를 검색할 수 있다고 알립니다.
+</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:scheme="http" android:type="video/*" /&gt;
+ ...
+&lt;/intent-filter&gt;</pre>
+
+
+
+<h3 id="imatch">인텐트 일치</h3>
+
+<p>인텐트를 인텐트 필터에 비교해 일치시키면 활성화할 대상 구성 요소를
+찾아낼 수 있을 뿐만 아니라, 기기에 있는 일련의 구성 요소에 대해
+무언가 알아낼 수도 있습니다. 예를 들어 홈 앱이 앱 시작 관리자를 채우려면
+
+{@link android.content.Intent#ACTION_MAIN} 작업과
+{@link android.content.Intent#CATEGORY_LAUNCHER} 카테고리를 지정하는 인텐트 필터를 가진 액티비티를 모두 찾아야 합니다.</p>
+
+<p>여러분의 애플리케이션도 인텐트 일치를 이와 비슷한 방식으로 사용할 수 있습니다.
+{@link android.content.pm.PackageManager}에는 {@code query...()}
+ 메서드 집합이 있어 특정 인텐트를 허용하는 구성 요소를 모두 반환할 수 있고,
+이와 유사한 일련의 {@code resolve...()} 메서드도 있어 한 인텐트에 응답하는 데
+가장 좋은 구성 요소를 판별할 수 있습니다. 예를 들어,
+{@link android.content.pm.PackageManager#queryIntentActivities
+queryIntentActivities()}는 인수로 통과한
+인텐트를 수행할 수 있는 모든 액티비티의 목록을 반환하며 {@link
+android.content.pm.PackageManager#queryIntentServices
+queryIntentServices()}는 이와 비슷한 서비스 목록을 반환합니다.
+양쪽 메서드 모두 구성 요소를 활성화하지는 않습니다. 다만 응답할 수 있는 것들을 목록으로
+나열할 뿐입니다. 이와 비슷한 메서드인
+{@link android.content.pm.PackageManager#queryBroadcastReceivers
+queryBroadcastReceivers()}는 브로드캐스트 수신기에 쓰입니다.
+</p>
+
+
+
+
diff --git a/docs/html-intl/intl/ko/guide/components/loaders.jd b/docs/html-intl/intl/ko/guide/components/loaders.jd
new file mode 100644
index 000000000000..cfbbb9133ed4
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/loaders.jd
@@ -0,0 +1,494 @@
+page.title=로더
+parent.title=액티비티
+parent.link=activities.html
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#summary">로더 API 요약</a></li>
+ <li><a href="#app">애플리케이션 안에서 로더 사용하기</a>
+ <ol>
+ <li><a href="#requirements"></a></li>
+ <li><a href="#starting">로더 시작</a></li>
+ <li><a href="#restarting">로더 다시 시작</a></li>
+ <li><a href="#callback">LoaderManager 콜백 사용하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#example">예</a>
+ <ol>
+ <li><a href="#more_examples">추가 예</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.app.LoaderManager}</li>
+ <li>{@link android.content.Loader}</li>
+
+ </ol>
+
+ <h2>관련 샘플</h2>
+ <ol>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a></li>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+LoaderThrottle</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>로더는 Android 3.0부터 도입된 것으로, 액티비티 또는 프래그먼트에서 비동기식으로 데이터를 쉽게
+로딩할 수 있게 합니다. 로더의 특성은 다음과 같습니다.</p>
+ <ul>
+ <li>모든 {@link android.app.Activity}와 {@link
+android.app.Fragment}에 사용할 수 있습니다.</li>
+ <li>데이터의 비동기식 로딩을 제공합니다.</li>
+ <li>데이터의 출처를 모니터링하여 그 콘텐츠가 변경되면 새 결과를
+전달합니다.</li>
+ <li>구성 변경 후에 재생성된 경우, 마지막 로더의 커서로 자동으로
+다시 연결됩니다. 따라서 데이터를 다시 쿼리하지 않아도
+됩니다.</li>
+ </ul>
+
+<h2 id="summary">로더 API 요약</h2>
+
+<p>애플리케이션 안에서 로더를 사용하는 데 관련된 클래스와 인터페이스는
+여러 가지가 있습니다. 다음 표에서 요약되어 있습니다.</p>
+
+<table>
+ <tr>
+ <th>클래스/인터페이스</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager}</td>
+ <td>{@link android.app.Activity} 또는
+{@link android.app.Fragment}와 연관된 추상 클래스로, 하나 이상의 {@link
+android.content.Loader} 인스턴스를 관리하는 데 쓰입니다. 이것을 사용하면 애플리케이션이
+{@link android.app.Activity}
+ 또는 {@link android.app.Fragment} 수명 주기와 함께 실행 시간이 긴 작업을 관리하는 데 도움이 됩니다. 이것의 가장 보편적인 용법은
+{@link android.content.CursorLoader}와 함께 사용하는 것이지만,
+다른 유형의 데이터를 로드하기 위해 애플리케이션이 자체 로더를 작성하는 것도 얼마든지 가능합니다.
+ <br />
+ <br />
+ 액티비티 또는 프래그먼트당 {@link android.app.LoaderManager}는 하나씩밖에 없습니다. 하지만 {@link android.app.LoaderManager}에는 로더가 여러 개 있어도
+됩니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager.LoaderCallbacks}</td>
+ <td>클라이언트에 대해 {@link
+android.app.LoaderManager}와 상호 작용하도록 하는 콜백 인터페이스입니다. 예를 들어 {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+콜백 메서드를 사용하여 새 로더를 생성할 수 있습니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.Loader}</td>
+ <td>데이터의 비동기식 로딩을 수행하는 추상 클래스입니다. 이것이 로더의 기본
+클래스입니다. 보통은 {@link
+android.content.CursorLoader}를 사용하기 마련이지만, 자신만의 하위 클래스를 구현해도 됩니다. 로더가 활성 상태인 동안에는
+소속 데이터의 출처를 모니터링하고 콘텐츠가 변경되면 새 결과를
+전달하는 것이 정상입니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.content.AsyncTaskLoader}</td>
+ <td>작업을 수행할 {@link android.os.AsyncTask}를 제공하는 추상 로더입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.CursorLoader}</td>
+ <td>{@link android.content.AsyncTaskLoader}의 하위 클래스로, 이것이
+{@link android.content.ContentResolver}를 쿼리하고 {@link
+android.database.Cursor}를 반환합니다. 이 클래스는 커서 쿼리에 대한 표준 방식으로 {@link
+android.content.Loader} 프로토콜을 구현하며,
+{@link android.content.AsyncTaskLoader}에 구축되어
+배경 스레드에서 커서 쿼리를 수행하므로 애플리케이션의 UI를 차단하지 않습니다.
+이 로더를 사용하는 것이 프래그먼트나 액티비티의 API를 통해 관리된 쿼리를 수행하는 대신 {@link
+android.content.ContentProvider}에서
+비동기식으로 데이터를 로딩하는 최선의 방법입니다.</td>
+ </tr>
+</table>
+
+<p>위의 표에 나열된 클래스와 인터페이스가 애플리케이션 내에서 로더를 구현하는 데
+사용할 기본적인 구성 요소입니다. 생성하는 로더마다
+이 모든 것이 다 필요한 것은 아니지만, 로더를 초기화하려면 항상 {@link
+android.app.LoaderManager}를 참조해야 하고 {@link
+android.content.CursorLoader}와 같은 {@link android.content.Loader}
+클래스도 구현해야 합니다. 다음 몇 섹션에서는 애플리케이션 안에서 이와 같은
+클래스와 인터페이스를 사용하는 법을 보여줍니다.</p>
+
+<h2 id ="app">애플리케이션 안에서 로더 사용하기</h2>
+<p>이 섹션에서는 Android 애플리케이션 내에서 로더를 사용하는 방법을 설명합니다. 로더를
+사용하는 애플리케이션에는 보통 다음이 포함되어 있습니다.</p>
+<ul>
+ <li>{@link android.app.Activity} 또는 {@link android.app.Fragment}.</li>
+ <li>{@link android.app.LoaderManager}의 인스턴스.</li>
+ <li>{@link
+android.content.ContentProvider}가 지원하는 데이터를 로딩할 {@link android.content.CursorLoader}. 아니면, 개발자 나름의
+{@link android.content.Loader} 또는 {@link android.content.AsyncTaskLoader} 하위 클래스를 구현하여
+다른 출처에서 데이터를 로딩해도 됩니다.</li>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks}의 구현.
+여기에서 새 로더를 생성하고 기존 로더에 대한 참조를
+관리합니다.</li>
+<li>로더의 데이터를 표시하는 방법(예: {@link
+android.widget.SimpleCursorAdapter})</li>
+ <li>{@link android.content.ContentProvider}와 같은 데이터 출처로,
+{@link android.content.CursorLoader}를 사용하는 경우에 해당.</li>
+</ul>
+<h3 id="starting">로더 시작</h3>
+
+<p>{@link android.app.LoaderManager}는 {@link android.app.Activity} 또는
+{@link android.app.Fragment} 내에서 하나 이상의 {@link
+android.content.Loader} 인스턴스를 관리합니다. 액티비티 또는 프래그먼트당 {@link
+android.app.LoaderManager}는 하나씩밖에 없습니다.</p>
+
+<p>보통은
+액티비티의 {@link
+android.app.Activity#onCreate onCreate()} 메서드 내에서, 또는 프래그먼트의
+{@link android.app.Fragment#onActivityCreated onActivityCreated()} 메서드 내에서 {@link android.content.Loader}를 초기화합니다. 이렇게 하려면
+다음과 같은 방법을 따릅니다.</p>
+
+<pre>// Prepare the loader. Either re-connect with an existing one,
+// or start a new one.
+getLoaderManager().initLoader(0, null, this);</pre>
+
+<p>{@link android.app.LoaderManager#initLoader initLoader()} 메서드는
+다음과 같은 인수를 취합니다.</p>
+<ul>
+ <li>로더를 식별하는 고유한 ID. 이 예시에서 ID는 0입니다.</li>
+<li>생성 시 로더에 제공할 선택적 인수
+(이 예시에서는 <code>null</code>).</li>
+
+<li>{@link android.app.LoaderManager.LoaderCallbacks} 구현. 로더 이벤트를 보고하기 위해
+{@link android.app.LoaderManager}가 이것을 호출합니다. 이 예시에서는
+ 로컬 클래스가 {@link
+android.app.LoaderManager.LoaderCallbacks} 인터페이스를 구현하여 자신에 대한 참조인
+{@code this}를 통과합니다.</li>
+</ul>
+<p>{@link android.app.LoaderManager#initLoader initLoader()} 호출로 로더가 초기화되었고 활성 상태이도록
+확실히 합니다. 이로써 발생할 수 있는 결과가 두 가지 있습니다.</p>
+<ul>
+ <li>ID가 지정한 로더가 이미 존재하는 경우, 마지막으로 생성된 로더를
+재사용합니다.</li>
+ <li>ID가 지정한 로더가 존재하지 <em>않는</em> 경우,
+{@link android.app.LoaderManager#initLoader initLoader()}가
+{@link android.app.LoaderManager.LoaderCallbacks} 메서드 {@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}를 발생시킵니다.
+여기에서 인스턴트화할 코드를 구현하고 새 로더를 반환합니다.
+자세한 논의는 <a href="#onCreateLoader">onCreateLoader</a> 섹션을 참조하십시오.</li>
+</ul>
+<p>어떤 경우에든 주어진 {@link android.app.LoaderManager.LoaderCallbacks}
+구현은 해당 로더와 연관되어 있으며, 로더 상태가 변경되면
+이것이 호출됩니다. 이 호출의 그러한 시점에서 발신자가
+시작된 상태에 있으며 요청한 로더가 이미 존재하고 자신의 데이터를
+생성해 놓은 경우, 시스템은 즉시 {@link
+android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}를
+호출합니다({@link android.app.LoaderManager#initLoader initLoader()} 도중).
+따라서 이런 일이 발생할 것에 대비해두어야만 합니다. 이 콜백에 대한 자세한 논의는 <a href="#onLoadFinished">
+onLoadFinished</a>를 참조하십시오.</p>
+
+<p>{@link android.app.LoaderManager#initLoader initLoader()}
+메서드는 생성된 {@link android.content.Loader}를 반환하지만, 이에 대한 참조를 캡처하지 않아도 된다는 점을
+유의하십시오. {@link android.app.LoaderManager}는 로더의 수명을
+자동으로 관리합니다. {@link android.app.LoaderManager}는
+필요에 따라 로딩을 시작하고 중단하며, 로더와 그에 연관된 콘텐츠의 상태를
+유지관리합니다. 이것이 시사하는 바와 같이, 로더와 직접적으로
+상호 작용하는 경우는 극히 드뭅니다(다만, 로더의 행동을 미세하게 조정하기 위해 로더 메서드를 사용하는 사례를 알아보려면
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> 샘플을 참조하면 좋습니다).
+가장 보편적으로 사용되는 메서드는 {@link
+android.app.LoaderManager.LoaderCallbacks}로, 이를 사용해 특정한 이벤트가 일어났을 때
+로딩 프로세스에 개입하게 됩니다. 이 주제에 대한 자세한 논의는 <a href="#callback">LoaderManager 콜백 사용하기</a>를 참조하십시오.</p>
+
+<h3 id="restarting">로더 다시 시작</h3>
+
+<p>위에서 나타난 것과 같이 {@link android.app.LoaderManager#initLoader initLoader()}를 사용하는 경우,
+이것은 지정된 ID에 해당되는 기존 로더가 있으면 그것을 사용합니다.
+없으면, 하나 생성합니다. 하지만 때로는 오래된 데이터를 폐기하고 새로 시작하고 싶을 때가
+있습니다.</p>
+
+<p>오래된 데이터를 폐기하려면 {@link
+android.app.LoaderManager#restartLoader restartLoader()}를 사용합니다. 예를 들어, 다음의
+{@link android.widget.SearchView.OnQueryTextListener} 구현은
+사용자의 쿼리가 변경되면 로더를 다시 시작합니다. 로더를 다시 시작해야 수정된 검색 필터를 사용하여
+새 쿼리를 수행할 수 있습니다.</p>
+
+<pre>
+public boolean onQueryTextChanged(String newText) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+}</pre>
+
+<h3 id="callback">LoaderManager 콜백 사용하기</h3>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks}는 클라이언트가
+{@link android.app.LoaderManager}와 상호 작용할 수 있게 해주는 콜백 인터페이스입니다. </p>
+<p>로더, 특히 {@link android.content.CursorLoader}는 중단된 후에도
+자신의 데이터를 유지할 것으로 기대됩니다. 이 때문에 애플리케이션이
+액티비티 또는 프래그먼트의 @link android.app.Activity#onStop
+onStop()} 및 {@link android.app.Activity#onStart onStart()}를 가로질러 데이터를 유지할 수 있고,
+따라서 사용자가 애플리케이션에 되돌아오면 데이터가 다시 로딩되기를 기다리지
+않아도 됩니다. 새 로더를 언제 생성해야 할지 알아보려면 {@link android.app.LoaderManager.LoaderCallbacks}
+메서드를 사용합니다. 또한 로더의 데이터 사용을 중단할 때가 되면
+이를 애플리케이션에 알리는 데에도 이것을 사용할 수 있습니다.</p>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks}에는 다음과 같은 메서드가
+포함됩니다.</p>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} -
+주어진 ID에 대하여 인스턴트화하고 새 {@link android.content.Loader}를 반환합니다.
+</li></ul>
+<ul>
+ <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+- 이전에 생성된 로더가 로딩을 완료하면 호출됩니다.
+</li></ul>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
+- 이전에 생성된 로더가 휴식 중이라서 해당되는 데이터를 사용할 수 없을 경우
+호출됩니다.
+</li>
+</ul>
+<p>이러한 메서드는 다음 섹션에 보다 자세하게 설명되어 있습니다.</p>
+
+<h4 id ="onCreateLoader">onCreateLoader</h4>
+
+<p>로더에 액세스하려 시도하는 경우(예를 들어 {@link
+android.app.LoaderManager#initLoader initLoader()}를 통해), 로더는 해당 ID가 지정하는 로더가 존재하는지
+여부를 확인합니다. 그런 로더가 없으면, {@link
+android.app.LoaderManager.LoaderCallbacks} 메서드 {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}를 발생시킵니다. 여기에서
+새 로더를 생성합니다. 이것은 보통 {@link
+android.content.CursorLoader}이지만, 개발자 나름대로 {@link
+android.content.Loader} 하위 클래스를 구현해도 됩니다. </p>
+
+<p>이 예시에서는, {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+ 콜백 메서드가 {@link android.content.CursorLoader}를 생성합니다.
+{@link android.content.CursorLoader}를 자체 생성자 메서드를 사용하여 구축해야 합니다. 이것은
+{@link
+android.content.ContentProvider}로 쿼리를 수행하기 위해 필요한 모든 정보 집합을 필요로 합니다. 구체적으로 필요한 것은 다음과 같습니다.</p>
+<ul>
+ <li><em>uri</em> — 검색할 콘텐츠의 URI입니다. </li>
+ <li><em>예측</em> — 반환할 열 목록입니다.
+<code>null</code>을 전달하면 모든 열을 반환하며, 이는 비효율적입니다. </li>
+ <li><em>선택</em> — 반환할 행을 선언하는 필터로,
+SQL WHERE 절로 형식이 설정됩니다(WHERE 자체는 제외).
+<code>null</code>을 반환하면 주어진 URI에 대한 모든 행을 반환합니다. </li>
+ <li><em>selectionArgs</em> — 선택에 ?를 포함해도 됩니다. 이렇게 하면
+이것이 <em>selectionArgs</em>에서 가져온 값으로 교체되며, 이때 선택에 표시되는
+순서를 따릅니다. 값은 문자열로 바인딩됩니다. </li>
+ <li><em>sortOrder</em> — SQL ORDER BY 절 형식으로 설정된
+행의 순서 지정 방법입니다(ORDER BY 자체는 제외). <code>null</code>을
+전달하면 기본 정렬 순서를 사용하는데, 이는 순서가 없습니다.</li>
+</ul>
+<p>예:</p>
+<pre>
+ // If non-null, this is the current filter the user has provided.
+String mCurFilter;
+...
+public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+ // This is called when a new Loader needs to be created.  This
+ // sample only has one Loader, so we don't care about the ID.
+ // First, pick the base URI to use depending on whether we are
+ // currently filtering.
+ Uri baseUri;
+    if (mCurFilter != null) {
+        baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                Uri.encode(mCurFilter));
+    } else {
+        baseUri = Contacts.CONTENT_URI;
+    }
+
+    // Now create and return a CursorLoader that will take care of
+    // creating a Cursor for the data being displayed.
+    String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
+            + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
+            + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
+    return new CursorLoader(getActivity(), baseUri,
+            CONTACTS_SUMMARY_PROJECTION, select, null,
+            Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
+}</pre>
+<h4 id="onLoadFinished">onLoadFinished</h4>
+
+<p>이 메서드는 이전에 생성된 로더가 로딩을 완료하면 호출됩니다.
+이 로더에 대해 제공된 마지막 데이터가 릴리스되기 전에 틀림없이
+이 메서드가 호출됩니다. 이 시점에서 오래된 데이터의
+사용 내용을 모두 제거해야 하지만(곧 릴리스될 것이므로), 데이터 릴리스를 직접 수행해서는 안 됩니다. 해당 데이터는
+로더의 소유이며, 로더가 알아서 처리할 것이기 때문입니다.</p>
+
+
+<p>로더는 애플리케이션이 데이터를 더 이상 사용하지 않는다는 사실을 알게 되면 곧바로 해당 데이터를
+릴리스할 것입니다. 예를 들어 데이터가 {@link
+android.content.CursorLoader}의 커서인 경우, 거기에서 직접 {@link
+android.database.Cursor#close close()}를 호출하면 안 됩니다. 커서가
+{@link android.widget.CursorAdapter}에 배치되는 경우, {@link
+android.widget.SimpleCursorAdapter#swapCursor swapCursor()} 메서드를 사용해야 합니다. 그래야
+오래된 {@link android.database.Cursor}가 종료되지 않습니다. 예:</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.<br
+/>SimpleCursorAdapter mAdapter;
+...
+
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
+ // Swap the new cursor in.  (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+}</pre>
+
+<h4 id="onLoaderReset">onLoaderReset</h4>
+
+<p>이 메서드는 이전에 생성된 로더가 휴식 중이라서 해당되는 데이터를 사용할 수 없는 경우
+호출됩니다. 이 콜백을 사용하면 데이터가 언제 릴리스될지 알아낼 수 있어
+이에 대한 참조를 직접 제거할 수 있습니다.  </p>
+<p>이 구현은
+{@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()}를 호출하며,
+이때 값은 <code>null</code>을 씁니다.</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.
+SimpleCursorAdapter mAdapter;
+...
+
+public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed.  We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+}</pre>
+
+
+<h2 id="example">예</h2>
+
+<p>일례를 제시하기 위해 아래에 {@link android.widget.ListView}를 표시하는 {@link
+android.app.Fragment}의 전체 구현을 나타내었습니다. 여기에는
+연락처 콘텐츠 제공자에 대한 쿼리 결과가 들어 있습니다. 이것은 {@link
+android.content.CursorLoader}를 사용하여 제공자에 대한 쿼리를 관리합니다.</p>
+
+<p>이 예시에서 나타낸 바와 같이 애플리케이션이 사용자의 연락처에 액세스하려면
+애플리케이션의 매니페스트에
+{@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS} 권한이 포함되어 있어야 합니다.</p>
+
+<pre>
+public static class CursorLoaderListFragment extends ListFragment
+        implements OnQueryTextListener, LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
+
+ // This is the Adapter being used to display the list's data.
+    SimpleCursorAdapter mAdapter;
+
+    // If non-null, this is the current filter the user has provided.
+    String mCurFilter;
+
+    @Override public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        // Give some text to display if there is no data.  In a real
+        // application this would come from a resource.
+        setEmptyText(&quot;No phone numbers&quot;);
+
+        // We have a menu item to show in action bar.
+        setHasOptionsMenu(true);
+
+        // Create an empty adapter we will use to display the loaded data.
+        mAdapter = new SimpleCursorAdapter(getActivity(),
+                android.R.layout.simple_list_item_2, null,
+                new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
+                new int[] { android.R.id.text1, android.R.id.text2 }, 0);
+        setListAdapter(mAdapter);
+
+        // Prepare the loader.  Either re-connect with an existing one,
+        // or start a new one.
+        getLoaderManager().initLoader(0, null, this);
+    }
+
+    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        // Place an action bar item for searching.
+        MenuItem item = menu.add(&quot;Search&quot;);
+        item.setIcon(android.R.drawable.ic_menu_search);
+        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        SearchView sv = new SearchView(getActivity());
+        sv.setOnQueryTextListener(this);
+        item.setActionView(sv);
+    }
+
+    public boolean onQueryTextChange(String newText) {
+        // Called when the action bar search text has changed.  Update
+        // the search filter, and restart the loader to do a new query
+        // with this filter.
+        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+        getLoaderManager().restartLoader(0, null, this);
+        return true;
+    }
+
+    @Override public boolean onQueryTextSubmit(String query) {
+        // Don't care about this.
+        return true;
+    }
+
+    @Override public void onListItemClick(ListView l, View v, int position, long id) {
+        // Insert desired behavior here.
+        Log.i(&quot;FragmentComplexList&quot;, &quot;Item clicked: &quot; + id);
+    }
+
+    // These are the Contacts rows that we will retrieve.
+    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
+        Contacts._ID,
+        Contacts.DISPLAY_NAME,
+        Contacts.CONTACT_STATUS,
+        Contacts.CONTACT_PRESENCE,
+        Contacts.PHOTO_ID,
+        Contacts.LOOKUP_KEY,
+    };
+    public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+        // This is called when a new Loader needs to be created.  This
+        // sample only has one Loader, so we don't care about the ID.
+        // First, pick the base URI to use depending on whether we are
+        // currently filtering.
+        Uri baseUri;
+        if (mCurFilter != null) {
+            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                    Uri.encode(mCurFilter));
+        } else {
+            baseUri = Contacts.CONTENT_URI;
+        }
+
+        // Now create and return a CursorLoader that will take care of
+        // creating a Cursor for the data being displayed.
+        String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
+                + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
+                + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
+        return new CursorLoader(getActivity(), baseUri,
+                CONTACTS_SUMMARY_PROJECTION, select, null,
+                Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
+    }
+
+    public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
+        // Swap the new cursor in.  (The framework will take care of closing the
+        // old cursor once we return.)
+        mAdapter.swapCursor(data);
+    }
+
+    public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+        // This is called when the last Cursor provided to onLoadFinished()
+        // above is about to be closed.  We need to make sure we are no
+        // longer using it.
+        mAdapter.swapCursor(null);
+    }
+}</pre>
+<h3 id="more_examples">추가 예</h3>
+
+<p>로더를 사용하는 법을 보여주는 몇 가지 다른 예가 <strong>ApiDemos</strong>에
+소개되어 있습니다.</p>
+<ul>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a> — 위에 표시된 코드 조각의 완전한
+버전입니다.</li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — 데이터가 변경될 때 콘텐츠 제공자가
+수행하는 쿼리의 수를 줄이기 위해 제한을 사용하는 방법을 예시로 나타낸 것입니다.</li>
+</ul>
+
+<p>SDK 샘플을 다운로드하고 설치하는 데 대한 정보는 <a href="http://developer.android.com/resources/samples/get.html">샘플
+가져오기</a>를 참조하십시오. </p>
+
diff --git a/docs/html-intl/intl/ko/guide/components/processes-and-threads.jd b/docs/html-intl/intl/ko/guide/components/processes-and-threads.jd
new file mode 100644
index 000000000000..850d55cf9c71
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/processes-and-threads.jd
@@ -0,0 +1,411 @@
+page.title=프로세스 및 스레드
+page.tags=수명 주기, 배경
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+<li><a href="#Processes">프로세스</a>
+ <ol>
+ <li><a href="#Lifecycle">프로세스 수명 주기</a></li>
+ </ol>
+</li>
+<li><a href="#Threads">스레드</a>
+ <ol>
+ <li><a href="#WorkerThreads">작업자 스레드</a></li>
+ <li><a href="#ThreadSafe">스레드로부터 안전한 메서드</a></li>
+ </ol>
+</li>
+<li><a href="#IPC">프로세스 간 통신</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>애플리케이션 구성 요소가 시작되고 애플리케이션에 실행 중인 다른 구성 요소가 없으면
+Android 시스템은 하나의 실행 스레드로 애플리케이션의 Linux 프로세스를
+시작합니다. 기본적으로 같은 애플리케이션의 모든 구성 요소는 같은 프로세스와 스레드에서 실행됩니다
+("기본" 스레드라고 합니다). 애플리케이션 구성 요소가 시작되고 (애플리케이션의 다른 구성 요소가 존재해서)
+해당 애플리케이션의 프로세스가 이미 존재하면 해당 구성 요소는
+프로세스 내에서 시작되고 같은 실행 스레드를 사용합니다. 하지만 애플리케이션 내의
+여러 가지 구성 요소가 각자 별도의 프로세스에서 실행되도록 할 수도 있고, 어느 프로세스에든 추가 스레드를
+만들 수 있습니다.</p>
+
+<p>이 문서는 프로세스와 스레드가 Android 애플리케이션에서 작동하는 방식을 설명합니다.</p>
+
+
+<h2 id="Processes">프로세스</h2>
+
+<p>기본적으로 같은 애플리케이션의 모든 구성 요소는 같은 프로세스와 스레드에서 실행되고,
+대부분의 애플리케이션은 이를 바꿔서는 안 됩니다. 그러나 어느 프로세스가 특정 구성 요소에 속하는지
+확인해야 할 경우 매니페스트 파일에서 확인할 수 있습니다.</p>
+
+<p>구성 요소 &mdash;<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a>와 <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code
+&lt;service&gt;}</a>, <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
+&lt;receiver&gt;}</a> 및 <a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code
+&lt;provider&gt;}</a>&mdash;의 각 유형에 대한 매니페스트 항목은 구성 요소를 실행할 프로세스를 지정하는 {@code android:process} 속성을 지원합니다.
+ 이러한 속성을 설정하여 각 구성 요소를 자체 프로세스에서 실행시키거나
+다른 구성 요소를 제외한 일부 구성 요소만 프로세스를 공유하게 할 수 있습니다 또한,
+{@code android:process}를 설정하여 다른 애플리케이션의 구성 요소를 같은 프로세스에서 실행시킬 수 있습니다.
+단, 이는 애플리케이션이 같은 Linux 사용자 ID를 공유하고 같은 인증서에
+서명되었을 경우에 한합니다.</p>
+
+<p><a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
+&lt;application&gt;}</a> 요소도 {@code android:process} 속성을 지원하여,
+모든 구성 요소에 적용되는 기본값을 설정합니다.</p>
+
+<p>Android는 어느 시점엔가 프로세스를 종료하기로 결정할 수도 있습니다. 즉 메모리가 부족하거나, 사용자에게 더욱 즉각적인 서비스를 제공하는
+다른 프로세스가 이 프로세스의 중단을 필요로 하는 경우 등입니다. 그러면 중단된
+프로세스에서 실행되고 있던 애플리케이션 구성 요소도 따라서 소멸됩니다. 그와 같은 구성 요소가 할 작업이 다시 생기면
+그에 대한 프로세스도 다시 시작됩니다.</p>
+
+<p>어느 프로세스를 삭제할지 결정할 때, Android 시스템은
+사용자에 대한 이들의 상대적 중요성을 가늠합니다. 예를 들어, 눈에 보이는 액티비티를 호스팅하는 프로세스와 비교하여
+화면에 보이지 않는 액티비티를 호스팅하는 프로세스를 쉽게 종료할 수 있습니다. 프로세스 종료 결정은
+해당 프로세스에서 실행되는 구성 요소의 상태에 따라 달라집니다. 종료할
+프로세스를 결정하는 데 사용하는 규칙은 아래에 설명되어 있습니다. </p>
+
+
+<h3 id="Lifecycle">프로세스 수명 주기</h3>
+
+<p>Android 시스템은 최대한 오래 애플리케이션 프로세스를 유지하려고 시도하지만,
+결국 오래된 프로세스를 제거하고 새 프로세스나 더 중요한 프로세스에 사용할 메모리를 확보해야 합니다. 유지할
+프로세스와 종료할 프로세스를 결정하기 위해
+시스템은 프로세스에서 실행되는 구성 요소와 해당 구성 요소의 상태에 기초하여 각 프로세스에
+"중요 계층"을 부여합니다. 중요도가 낮은
+프로세스가 먼저 제거되고, 그 다음으로 중요도가 낮은 프로세스를 제거하는 식으로
+필요에 따라 시스템 리소스를 회복하는 것입니다.</p>
+
+<p>중요 계층에는 다섯 가지 단계가 있습니다. 다음 목록은
+중요도 순서에 따른 프로세스 유형을 나타낸 것입니다(첫 번째 프로세스가 <em>가장 중요하고</em>
+<em>마지막으로 종료됩니다)</em>.</p>
+
+<ol>
+ <li><b>전경 프로세스</b>
+ <p>사용자가 현재 진행하는 작업에 필요한 프로세스입니다. 다음 조건 중
+하나가 참일 경우 프로세스가 전경에 있는 것으로 간주합니다.</p>
+
+ <ul>
+ <li>사용자와 상호 작용하는 {@link android.app.Activity}를 호스팅할 경우({@link
+android.app.Activity}의 {@link android.app.Activity#onResume onResume()} 메서드가 호출되었을 경우
+).</li>
+
+ <li>사용자와 상호 작용하는 액티비티에 바인딩된 {@link android.app.Service}를 호스팅할 경우.
+</li>
+
+ <li>"전경에서" 실행되는 {@link android.app.Service}를 호스팅할 경우(
+해당 서비스가 {@link android.app.Service#startForeground startForeground()}를 호출했을 경우).
+
+ <li>수명 주기 콜백 중 하나를 실행하는 {@link android.app.Service}를 호스팅할 경우
+({@link android.app.Service#onCreate onCreate()}, {@link android.app.Service#onStart
+onStart()} 또는 {@link android.app.Service#onDestroy onDestroy()}).</li>
+
+ <li>{@link
+android.content.BroadcastReceiver#onReceive onReceive()} 메서드를 실행하는 {@link android.content.BroadcastReceiver}를 호스팅할 경우.</li>
+ </ul>
+
+ <p>일반적으로, 주어진 시간에 존재하는 전경 프로세스는 몇 개밖에 되지 않습니다. 이들은 최후의
+수단으로서만 종료됩니다. 즉, 메모리가 너무 부족해 계속 실행할 수 없는 경우를 말합니다. 일반적으로 그 시점이 되면
+기기가 메모리 페이징 상태에 도달한 것이므로 전경 프로세스 몇 개를 중단해야만
+사용자 인터페이스의 반응성을 유지할 수 있습니다.</p></li>
+
+ <li><b>가시적 프로세스</b>
+ <p>전경 구성 요소는 없지만
+사용자가 화면에서 보는 것에 영향을 미칠 수 있는 프로세스입니다. 다음 조건 중 하나가 참이면
+가시적 프로세스로 간주합니다.</p>
+
+ <ul>
+ <li>전경에 있지는 않지만 사용자에게 보이는 {@link android.app.Activity}를 호스팅할 경우
+({@link android.app.Activity#onPause onPause()} 메서드가 호출되었을 경우).
+예를 들어 이것은 전경 액티비티가 대화를 시작하여 이전 액티비티가 그 뒤에 보일 경우
+ 발생합니다.</li>
+
+ <li>눈에 보이는(또는 전경) 액티비티에 바인딩된 {@link android.app.Service}를 호스팅할 경우.
+</li>
+ </ul>
+
+ <p>가시적인 프로세스는 매우 중요도가 높은 것으로 취급하고 모든 전경 프로세스를 실행하는 데 필요할 경우에만
+종료됩니다. </p>
+ </li>
+
+ <li><b>서비스 프로세스</b>
+ <p>{@link
+android.content.Context#startService startService()} 메서드로 시작되었지만 두 개의 상위 계층 분류에
+들어가지 않는 서비스를 실행하는 프로세스입니다. 서비스 프로세스는 사용자가 보는 것과 직접 연결되어 있지는 않지만,
+일반적으로 사용자가 신경 쓰는 작업을 하므로(배경에서 음악 재생 또는 네트워크에서 데이터 다운로드)
+시스템은 모든 전경 및 가시적 프로세스와 함께 실행할 만큼 메모리가 충분하지 않을 경우에만
+프로세스를 중단합니다. </p>
+ </li>
+
+ <li><b>배경 프로세스</b>
+ <p>현재 사용자에게 보이지 않는 액티비티를 보유한 프로세스입니다(액티비티의
+{@link android.app.Activity#onStop onStop()} 메서드가 호출되었습니다). 이와 같은 프로세스는
+사용자 환경에 직접적 영향을 미치지 않고, 시스템은 언제든 이 프로세스를 중단시켜
+전경,
+가시적 또는 서비스 프로세스를 위한 메모리를 확보할 수 있습니다. 보통 한번에 실행 중인 배경 프로세스가 많은 편이므로 이들은
+LRU(최저 사용 빈도) 목록에 보관하여 사용자가 가장 최근에 본 액티비티가 있는
+프로세스가 가장 마지막에 중단되도록 합니다. 액티비티가 수명 주기 메서드를 올바르게 구현하고
+자신의 현재 상태를 저장할 경우, 사용자가 액티비티로 다시 이동할 때 액티비티가 모든 가시적 상태를
+복원하므로 프로세스를 중단시키더라도 사용자 환경에는 눈에 띄게 영향을 미치지
+않습니다. 상태 저장과 복원에 관한 정보는 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">액티비티</a>
+문서를 참조하십시오.</p>
+ </li>
+
+ <li><b>빈 프로세스</b>
+ <p>활성 애플리케이션 구성 요소를 보유하지 않은 프로세스입니다. 이런 프로세스를
+유지하는 유일한 이유는 다음에 내부 구성 요소를 실행할 때 시작 시간을 절약하기 위한 캐싱
+때문입니다. 시스템은 프로세스 캐시와 기본 커널 캐시 사이에서 전반적인 시스템 리소스의 균형을 맞추기 위해
+이 프로세스를 중단시키는 경우가 많습니다.</p>
+ </li>
+</ol>
+
+
+ <p>Android는 프로세스에서 현재 활성 상태인 구성 요소의 중요도에 따라
+프로세스에 가장 높은 수준을 부여합니다. 예를 들어, 프로세스가 서비스와 가시적 액티비티를 호스팅할 경우,
+해당 프로세스는 서비스 프로세스가 아니라 가시적 프로세스 등급이 부여됩니다.</p>
+
+ <p>또한, 프로세스의 등급은 다른 프로세스가 이에 의존할 경우 상승할 수 있습니다.
+즉, 다른 프로세스에 서비스를 제공하는 프로세스가 서비스 제공 대상 프로세스보다
+등급이 낮은 경우는 있을 수 없습니다. 예를 들어 프로세스 A의 콘텐츠 제공자가 프로세스 B의 클라이언트에 서비스를 제공하거나
+프로세스 A의 서비스가 프로세스 B의 구성 요소에 바인딩되어 있을 경우 프로세스 A는 항상 중요도가
+프로세스 B와 같거나 그보다 높습니다.</p>
+
+ <p>서비스를 실행하는 프로세스가 배경 액티비티가 포함된 프로세스보다 높으므로,
+장기 작업을 시작하는 액티비티는 작업자 스레드만 생성하기보다는 해당 작업에 대한 <a href="{@docRoot}guide/components/services.html">서비스</a>를 시작하는 것이 좋습니다.
+이는 특히 작업이 해당 액티비티보다 오래 지속될 경우 더욱 중요합니다.
+예를 들어, 웹사이트에 사진을 업로드하는 액티비티가 업로드를 수행하는 서비스를 시작해야
+사용자가 액티비티를 떠나더라도 배경에서 업로드를 지속할 수 있습니다.
+서비스를 사용하면 액티비티에 어떤 일이 발생하든 해당 작업에 반드시
+"서비스 프로세스" 우선 순위 이상이 부여됩니다. 이것이 브로드캐스트 수신기가 시간이 오래 걸리는 작업을
+스레드에 넣기보다는 서비스를 사용해야 하는 것과 같은 이유입니다.</p>
+
+
+
+
+<h2 id="Threads">스레드</h2>
+
+<p> 애플리케이션이 시작되면 시스템이 애플리케이션에 대한 실행의 스레드를 생성하며, 이를
+"기본"이라고 합니다. 이 스레드는 드로어블 이벤트를 포함하여 적절한 사용자 인터페이스 위젯에
+이벤트를 발송하는 역할을 맡기 때문에 중요합니다. 이것은 Android UI 도구 키트의 구성 요소({@link
+android.widget}과 {@link android.view} 패키지의 구성 요소)와 개발자의 애플리케이션이
+상호 작용하는 스레드이기도 합니다. 따라서 기본 스레드는
+UI 스레드라고 불릴 때도 있습니다.</p>
+
+<p>시스템은 구성 요소의 각 인스턴스에 대해 별도의 스레드를 생성하지 <em>않습니다</em>. 같은
+프로세스에서 실행되는 모든 구성 요소는 UI 스레드에서 시작되고, 각 구성 요소를 호출하는 시스템이
+해당 스레드에서 발송됩니다. 따라서
+시스템 콜백에 응답하는 메서드(사용자 작업을 보고하는 {@link android.view.View#onKeyDown onKeyDown()} 또는
+수명 주기 콜백 메서드)는 항상 프로세스의 UI 스레드에서 실행됩니다.</p>
+
+<p>예를 들어, 사용자가 화면의 버튼을 터치하면, 앱 UI 스레드가 위젯에 터치 이벤트를 발송하고,
+위젯은 눌린 상태를 설정하고 이벤트 대기열에
+무효화 요청을 게시합니다. UI 스레드가 이 요청을 대기열에서 해제하고 위젯에 스스로를 다시
+그려야 한다고 알립니다.</p>
+
+<p>앱이 사용자 상호작용에 응답하여 집약적인 작업을 수행할 때는 이 단일 스레드 모델은
+애플리케이션을 제대로 구현하지 않으면 낮은 성능을 보일 수 있습니다. 특히,
+모든 것이 UI 스레드에서 발생하고 네트워크 액세스나 데이터 베이스 쿼리 등의 긴 작업을 수행하면
+UI가 통째로 차단됩니다. 스레드가 차단되면 드로잉 이벤트를 포함하여
+모든 이벤트가 발송되지 않습니다. 사용자가 보기에는 애플리케이션이
+중단된 것처럼 보입니다. 더 나쁜 경우, UI 스레드가 몇 초 이상 차단되어 있으면
+(현재 약 5초) 사용자에게 악명 높은 "<a href="http://developer.android.com/guide/practices/responsiveness.html">애플리케이션이 응답하지
+않습니다</a>"(ANR) 대화가 표시됩니다. 그러면 사용자가 여러분의 애플리케이션을 종료 할 수도 있고, 불만족한 경우 앱을
+제거할 수도 있습니다.</p>
+
+<p>또한, Andoid UI 도구 키트는 스레드로부터 안전하지 <em>않습니다</em>. 따라서 UI를
+작업자 스레드에서 조작해서는 안 됩니다. 사용자 인터페이스 조작 작업은 모두 UI
+스레드에서 해야만 합니다. 결론적으로, Android의 단일 스레드 모델에는 두 가지 단순한 규칙이 있습니다.</p>
+
+<ol>
+<li>UI 스레드를 차단하지 마십시오.
+<li>Ui 스레드 외부에서 Android UI 도구 키트에 액세스하지 마십시오.
+</ol>
+
+<h3 id="WorkerThreads">작업자 스레드</h3>
+
+<p>위에 설명한 단일 스레드 모델로 인해, 애플리케이션 UI의 반응성을 위해서는
+UI 스레드를 차단하지 않는 것이 매우 중요합니다. 수행해야 할 작업이 있는데
+이들이 즉각적인 조치를 요하지 않는 경우, 이런 작업은 반드시 별도의 스레드에서 수행해야 합니다("배경" 또는
+"작업자" 스레드).</p>
+
+<p>예를 들어, 아래는 별도의 스레드에서 이미지를 다운로드하고 이를
+{@link android.widget.ImageView}에 표시하는 클릭 수신기에 대한 몇 가지 코드입니다.</p>
+
+<pre>
+public void onClick(View v) {
+ new Thread(new Runnable() {
+ public void run() {
+ Bitmap b = loadImageFromNetwork("http://example.com/image.png");
+ mImageView.setImageBitmap(b);
+ }
+ }).start();
+}
+</pre>
+
+<p>처음에는 네트워크 작업을 처리하기 위한 새 스레드를 생성하므로
+아무 문제 없이 작동하는 것처럼 보입니다. 하지만, 이것은 단일 스레드된 모델의 두 번째 규칙 즉, '<em>UI 스레드 외부에서
+Android UI 도구 키트에 액세스하지 마세요.</em>'를 위반합니다. 이 샘플은 UI 스레드 대신 작업자 스레드에서 {@link
+android.widget.ImageView}를 수정합니다. 이렇게 되면
+정의되지 않고 예기치 못한 동작이 발생하는 결과를 초래할 수 있고, 이는 추적하기 어려워 시간도 오래 걸립니다.</p>
+
+<p>이 문제를 해결하기 위해 Android는 다른 스레드에서 UI 스레드에 액세스하는 여러 가지 방식을
+제안합니다. 다음은 몇 가지 유용한 메서드 목록입니다.</p>
+
+<ul>
+<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable)
+Activity.runOnUiThread(Runnable)}</li>
+<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li>
+<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable,
+long)}</li>
+</ul>
+
+<p>예를 들어 위의 코드를 수정하려면 {@link
+android.view.View#post(java.lang.Runnable) View.post(Runnable)} 메서드를 사용하면 됩니다.</p>
+
+<pre>
+public void onClick(View v) {
+ new Thread(new Runnable() {
+ public void run() {
+ final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
+ mImageView.post(new Runnable() {
+ public void run() {
+ mImageView.setImageBitmap(bitmap);
+ }
+ });
+ }
+ }).start();
+}
+</pre>
+
+<p>이 구현은 이제 스레드로부터 안전합니다. 네트워크 작업은 별도의 스레드에서 수행된 반면
+{@link android.widget.ImageView}는 UI 스레드에서 조작되었기 때문입니다.</p>
+
+<p>그러나, 작업이 복잡해질수록 이런 종류의 코드가 더 복잡해질 수 있고 유지 관리하기
+까다로워질 수 있습니다. 더 복잡한 상호 작용을 작업자 스레드로 처리하려면, 작업자 스레드에서
+{@link android.os.Handler}를 사용하여 UI 스레드에서 전달 받은 메시지를 처리하는 방안을
+고려해보십시오. 하지만 최선의 해결책은 {@link android.os.AsyncTask} 클래스를 확장하는 방법일 것입니다.
+이것은 UI와 상호 작용해야 하는 작업자 스레드 작업의 실행을 단순화합니다.</p>
+
+
+<h4 id="AsyncTask">AsyncTask 사용</h4>
+
+<p>{@link android.os.AsyncTask}를 사용하면 사용자 인터페이스에서 비동기식 작업을 수행할 수
+있게 해줍니다. 이것은 작업자 스레드에서 차단 작업을 수행하고 그런 다음 그 결과를 UI 스레드에
+게시하며, 개발자가 직접 스레드 및/또는 처리기를 처리할 필요가 없습니다.</p>
+
+<p>이를 사용하려면 우선 {@link android.os.AsyncTask}를 하위 클래스로 한 다음 {@link
+android.os.AsyncTask#doInBackground doInBackground()} 콜백 메서드를 구현해야 합니다. 이것은 여러 가지
+배경 스레드에서 실행됩니다. UI를 업데이트하려면 {@link
+android.os.AsyncTask#onPostExecute onPostExecute()}를 구현해야 합니다. 이는 {@link
+android.os.AsyncTask#doInBackground doInBackground()}로부터의 결과를 전달하며 UI 스레드에서 실행되므로,
+안전하게 UI를 업데이트할 수 있습니다. 그런 다음 UI 스레드에서 {@link android.os.AsyncTask#execute execute()}를
+호출하여 해당 작업을 실행하면 됩니다.</p>
+
+<p>예를 들어, 이런 방식으로 {@link android.os.AsyncTask}를 사용하여
+이전의 예시를 구현할 수 있습니다.</p>
+
+<pre>
+public void onClick(View v) {
+ new DownloadImageTask().execute("http://example.com/image.png");
+}
+
+private class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
+ /** The system calls this to perform work in a worker thread and
+ * delivers it the parameters given to AsyncTask.execute() */
+ protected Bitmap doInBackground(String... urls) {
+ return loadImageFromNetwork(urls[0]);
+ }
+
+ /** The system calls this to perform work in the UI thread and delivers
+ * the result from doInBackground() */
+ protected void onPostExecute(Bitmap result) {
+ mImageView.setImageBitmap(result);
+ }
+}
+</pre>
+
+<p>이제 UI는 안전하고 코드는 더욱 단순해졌습니다. 작업을 작업자 스레드에서 수행되어야 하는
+부분과 UI 스레드에서 수행되어야 하는 부분으로 구분하기 때문입니다.</p>
+
+<p>이 클래스를 사용하는 법을 완전히 숙지하려면 {@link android.os.AsyncTask} 참조를
+읽어보시는 것이 좋습니다. 개괄적인 작동 방식은 아래에 간략히 소개해 놓았습니다.</p>
+
+<ul>
+<li>매개 변수의 유형, 진행률 값과 작업의 최종 값을 제네릭을 사용하여
+지정할 수 있습니다.</li>
+<li>메서드 {@link android.os.AsyncTask#doInBackground doInBackground()}는 작업자 스레드에서 자동으로
+실행됩니다.</li>
+<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}, {@link
+android.os.AsyncTask#onPostExecute onPostExecute()} 및 {@link
+android.os.AsyncTask#onProgressUpdate onProgressUpdate()}는 모두 UI 스레드에서 호출됩니다.</li>
+<li>{@link android.os.AsyncTask#doInBackground doInBackground()}가 반환한 값이
+{@link android.os.AsyncTask#onPostExecute onPostExecute()}로 전송됩니다.</li>
+<li>언제든 {@link android.os.AsyncTask#publishProgress publishProgress()}를 {@link
+android.os.AsyncTask#doInBackground doInBackground()}에서 호출하여 UI 스레드에서 {@link
+android.os.AsyncTask#onProgressUpdate onProgressUpdate()}를 실행하도록 할 수 있습니다.</li>
+<li>모든 스레드에서 언제든 작업을 취소할 수 있습니다.</li>
+</ul>
+
+<p class="caution"><strong>주의:</strong> 작업자 스레드를 사용할 때 마주칠 수 있는 또 한 가지 문제는
+<a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 구성 변경</a>으로 인해 액티비티가 예기치 못하게 다시 시작되는 것입니다
+(예를 들어 사용자가 화면 방향을 바꾸는 경우). 이 경우 작업자 스레드를 소멸시킬 수 있습니다.
+스레드가 재시작될 때 작업을 지속하는 방법과 액티비티가 제거되었을 때 작업을 적절히 취소하는 방법은
+<a href="http://code.google.com/p/shelves/">Shelves</a> 샘플 애플리케이션의 소스 코드를 참조하십시오.</p>
+
+
+<h3 id="ThreadSafe">스레드로부터 안전한 메서드</h3>
+
+<p> 어떤 경우에는 구현하는 메서드가 하나 이상의 스레드에서 호출되는 일도 있습니다. 따라서
+이를 스레드로부터 안전하게 작성해야만 합니다. </p>
+
+<p>이것은 주로 원격으로 호출할 수 있는 메서드에 대해 참입니다. 예를 들어 <a href="{@docRoot}guide/components/bound-services.html">바인딩된 서비스</a> 내의 메서드 등이 해당됩니다.
+{@link android.os.IBinder}에서 구현된 메서드가
+{@link android.os.IBinder IBinder}가 실행되는 프로세스에서 호출될 경우, 해당 메서드는 발신자의 스레드에서 실행됩니다.
+그러나 호출이 다른 프로세스에서 발생하면, 해당 메서드는 시스템이
+{@link android.os.IBinder
+IBinder}와 같은 프로세스에 유지하는 스레드 풀에서 선택된 스레드에서 실행됩니다(프로세스의 UI 스레드에서 실행되지 않습니다). 예를 들어, 어느 서비스의
+{@link android.app.Service#onBind onBind()} 메서드는 해당 서비스
+프로세스의 UI 스레드에서 호출되고, {@link android.app.Service#onBind
+onBind()}가 반환하는 객체에서 구현된 메서드는(예: RPC 메서드를 구현하는 하위 클래스) 해당 풀 안의 여러 스레드에서
+호출되게 됩니다. 서비스에 클라이언트가 하나 이상 있을 수 있으므로, 하나 이상의 풀이
+동시에 같은 {@link android.os.IBinder IBinder} 메서드에 참여할 수 있습니다. 그러므로 {@link android.os.IBinder
+IBinder} 메서드는 스레드로부터 안전하게 구현되어야 합니다.</p>
+
+<p> 마찬가지로 콘텐츠 제공자는 다른 프로세스에서 발생한 데이터 요청을 수신할 수 있습니다.
+{@link android.content.ContentResolver}와 {@link android.content.ContentProvider}
+클래스가 세부적인 프로세스 간 통신의 관리 방식을 숨길 수는 있지만, 이러한 요청에 응답하는 {@link
+android.content.ContentProvider} 메서드(&mdash;{@link
+android.content.ContentProvider#query query()}, {@link android.content.ContentProvider#insert
+insert()}, {@link android.content.ContentProvider#delete delete()}, {@link
+android.content.ContentProvider#update update()} 및 {@link android.content.ContentProvider#getType
+getType()} 메서드&mdash;)가 프로세스의 UI 스레드가 아니라
+콘텐츠 제공자 프로세스의 스레드 풀에서 호출됩니다. 이러한 메서드가 동시에 몇 개의 스레드에서 호출될 수 있으므로,
+스레드로부터 안전하게 구현되어야 합니다. </p>
+
+
+<h2 id="IPC">프로세스 간 통신</h2>
+
+<p>Android는 원격 프로시저 호출(RPC)을 사용한 프로세스 간 통신(IPC) 메커니즘을 제공합니다.
+여기서 메서드는 액티비티나 다른 애플리케이션 구성 요소에 호출되지만
+원격으로 (또 다른 프로세스에서) 실행되고, 결과는 모두 발신자에게 되돌려
+보냅니다. 메서드 호출과 메서드의 데이터는 운영 체제가 이해할 수 있는 수준으로 분해되고,
+로컬 프로세스와 주소 공간에서 원격 프로세스와 주소 공간으로 전송된 다음
+다시 결합되어 여기서 호출에 다시 응답합니다. 그런 다음 반환 값이
+반대 방향으로 전송됩니다. Android가 이와 같은 IPC 트랜잭션을 수행하는 데 필요한
+모든 코드를 제공하므로, 개발자는 그저 RPC 프로그래밍 인터페이스를 정의하고 구현하는 데에만 집중하면 됩니다. </p>
+
+<p>IPC를 수행하려면 애플리케이션이 반드시 서비스에 바인딩되어야만 하며, 이때 {@link
+android.content.Context#bindService bindService()}를 사용해야 합니다. 자세한 정보는 <a href="{@docRoot}guide/components/services.html">서비스</a> 개발자 가이드를 참조하십시오.</p>
+
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For information about how to perform work in the background for an indefinite period of time
+(without a user interface), continue with the <b><a
+href="{@docRoot}guide/components/services.html">Services</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/ko/guide/components/recents.jd b/docs/html-intl/intl/ko/guide/components/recents.jd
new file mode 100644
index 000000000000..cba3c45da3da
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/recents.jd
@@ -0,0 +1,256 @@
+page.title=개요 화면
+page.tags="recents","overview"
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#adding">개요 화면에 작업 추가</a>
+ <ol>
+ <li><a href="#flag-new-doc">작업 추가에 인텐트 플래그 사용</a></li>
+ <li><a href="#attr-doclaunch">작업 추가에 액티비티 특성 사용</a></li>
+ </ol>
+ </li>
+ <li><a href="#removing">작업 제거</a>
+ <ol>
+ <li><a href="#apptask-remove">작업 제거에 AppTask 클래스 사용</a></li>
+ <li><a href="#retain-finished">완료된 작업 보존</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.app.ActivityManager.AppTask}</li>
+ <li>{@link android.content.Intent}</li>
+ </ol>
+
+ <h2>샘플 코드</h2>
+ <ol>
+ <li><a href="{@docRoot}samples/DocumentCentricApps/index.html">문서 중심 앱</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>개요 화면(다른 말로 최근 사용 화면, 최근 작업 목록 또는 최근 앱이라고도 함)은
+시스템 수준 UI로, 최근에 액세스한 <a href="{@docRoot}guide/components/activities.html">
+액티비티</a> 및 <a href="{@docRoot}guide/components/tasks-and-back-stack.html">작업</a>을 목록으로 나열한 것입니다. 사용자는
+목록을 가로질러 이동하며 작업을 선택해서 재개할 수도 있고, 아니면
+목록에서 한 작업을 스와이프하여 밀어내어 목록에서 제거할 수도 있습니다. Android 5.0 릴리스(API 레벨 21)의 경우, 같은 액티비티의 여러 인스턴스에
+각기 다른 문서가 담겨 있는 경우 이들이 개요 화면에 작업으로 나타날 수 있습니다. 예를 들어
+Google Drive에 여러 개의 Google 문서 각각에 대한 작업이 있을 수 있습니다. 각 문서는 개요 화면에 하나의
+작업으로 나타납니다.</p>
+
+<img src="{@docRoot}images/components/recents.png" alt="" width="284" />
+<p class="img-caption"><strong>그림 1.</strong> 세 개의 Google Drive 문서가 각기 별도의
+작업을 나타내는 모습을 표시한 개요 화면입니다.</p>
+
+<p>보통은 개요 화면에 작업과 액티비티가 어떻게 표현될지는 시스템이
+정의하도록 두어야 합니다. 이 행동을 개발자가 수정할 필요도 없습니다.
+하지만, 개요 화면에 액티비티가 언제, 어떻게 나타날지는 앱이 결정할 수 있습니다.
+{@link android.app.ActivityManager.AppTask} 클래스를 사용하면 작업을 관리할 수 있게 해주고,
+{@link android.content.Intent} 클래스의 액티비티 플래그를 사용하면 개요 화면에서 액티비티가 추가되거나 제거되는 시점을
+지정할 수 있습니다. 또한, <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">
+&lt;activity&gt;</a></code> 특성을 사용하면 매니페스트에서의 동작을 설정할 수 있습니다.</p>
+
+<h2 id="adding">개요 화면에 작업 추가</h2>
+
+<p>{@link android.content.Intent} 클래스의 플래그를 사용하여 작업을 추가하면
+개요 화면에서 문서가 열리거나 다시 열리는 시점과 방법을 보다 철저히 통제할 수 있습니다.
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 특성을 사용하는 경우, 문서를 항상 새 작업에서 여는 방법과 기존 작업을 해당 문서에 다시 사용하는 방법 중에서
+선택할 수 있습니다.</p>
+
+<h3 id="flag-new-doc">작업 추가에 인텐트 플래그 사용</h3>
+
+<p>액티비티를 위해 새 문서를 생성하는 경우,
+{@link android.app.ActivityManager.AppTask} 클래스의
+{@link android.app.ActivityManager.AppTask#startActivity(android.content.Context, android.content.Intent, android.os.Bundle) startActivity()}
+ 메서드를 호출하고, 이것을 액티비티를 시작하는 인텐트에 전달하면 됩니다. 논리적인 중단을 삽입하여 시스템이 개요 화면에서 액티비티를
+새 작업으로 처리하도록 하려면, {@link android.content.Intent}의
+{@link android.content.Intent#addFlags(int) addFlags()} 메서드에 있는 {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+플래그를 전달하여 액티비티를 시작하도록 합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+플래그가 {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET} 플래그를
+대체합니다. 이것은 Android 5.0(API 레벨 21)부터 사용이 중단되었습니다.</p>
+
+<p>새 문서를 생성하면서 {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} 플래그를 설정하는 경우,
+시스템은 항상 대상 액티비티를 루트로 하여 새 작업을 만듭니다.
+이렇게 설정하면 같은 문서를 하나 이상의 작업에서 열 수 있습니다. 다음 코드는 기본 액티비티가 이 작업을 수행하는 방법을
+보여줍니다.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+DocumentCentricActivity.java</a></p>
+<pre>
+public void createNewDocument(View view) {
+ final Intent newDocumentIntent = newDocumentIntent();
+ if (useMultipleTasks) {
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ }
+ startActivity(newDocumentIntent);
+ }
+
+ private Intent newDocumentIntent() {
+ boolean useMultipleTasks = mCheckbox.isChecked();
+ final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+ newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
+ return newDocumentIntent;
+ }
+
+ private static int incrementAndGet() {
+ Log.d(TAG, "incrementAndGet(): " + mDocumentCounter);
+ return mDocumentCounter++;
+ }
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> {@code FLAG_ACTIVITY_NEW_DOCUMENT}
+ 플래그로 시작된 액티비티의 경우, 반드시 매니페스트에 {@code android:launchMode="standard"} 특성 값(기본)이 설정되어
+있어야 합니다.</p>
+
+<p>기본 액티비티가 새 액티비티를 시작하면 시스템은 기존의 작업을 검색하여 그 중
+해당 액티비티에 대한 인텐트 구성 요소 이름과 인텐트 데이터와 일치하는 인텐트를 가진 작업을 찾습니다. 그러한 작업을
+찾을 수 없거나 {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}
+ 플래그에 들어 있는 인텐트를 찾을 수 없는 경우, 해당 액티비티를 루트로 하여 새 작업이 생성됩니다. 원하는 항목을 찾으면, 시스템은 해당 작업을 전경으로 가지고 와
+새 인텐트를 {@link android.app.Activity#onNewIntent onNewIntent()}에 전달합니다.
+새 액티비티가 인텐트를 받아 개요 화면에서 새 문서를 생성하며, 이는 다음 예시에 나타낸
+것과 같습니다.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+NewDocumentActivity.java</a></p>
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_new_document);
+ mDocumentCount = getIntent()
+ .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0);
+ mDocumentCounterTextView = (TextView) findViewById(
+ R.id.hello_new_document_text_view);
+ setDocumentCounterText(R.string.hello_new_document_counter);
+}
+
+&#64;Override
+protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity
+ is reused to create a new document.
+ */
+ setDocumentCounterText(R.string.reusing_document_counter);
+}
+</pre>
+
+
+<h3 id="#attr-doclaunch">작업 추가에 액티비티 특성 사용</h3>
+
+<p>액티비티는 자신의 매니페스트에 새 작업을 시작할 때는 항상
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 특성, <a href="{@docRoot}guide/topics/manifest/activity-element.html#dlmode">
+{@code android:documentLaunchMode}</a>를 사용한다고 나타낼 수도 있습니다. 이 특성에는 네 가지 값이 있어 사용자가 애플리케이션으로 문서를 열면
+다음과 같은 효과를 발생시킵니다.</p>
+
+<dl>
+ <dt>"{@code intoExisting}"</dt>
+ <dd>액티비티가 문서에 대해 기존의 작업을 재사용합니다. 이것은
+{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} 플래그를 설정할 때
+{@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} 플래그 <em>없이</em> 설정하는 것과 같습니다.
+이는 위의 <a href="#flag-new-doc">작업 추가에 인텐트 플래그 사용</a>에서 설명한 것과 같습니다.</dd>
+
+ <dt>"{@code always}"</dt>
+ <dd>액티비티가 문서에 대해 새 작업을 생성하며, 이는 문서가 이미 열려 있는 경우라도 마찬가지입니다. 이 값을
+사용하는 것은 {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+ 및 {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} 플래그를 둘 다 설정하는 것과 같습니다.</dd>
+
+ <dt>"{@code none”}"</dt>
+ <dd>액티비티가 문서에 대해 새 작업을 생성하지 않습니다. 개요 화면은 액티비티를 기본 상태에서와
+같이 다룹니다. 즉 앱에 대한 하나의 작업을 표시하며, 이때 사용자가
+마지막으로 호출한 작업이 무엇이든 관계 없이 그 작업에서부터 재개합니다.</dd>
+
+ <dt>"{@code never}"</dt>
+ <dd>액티비티가 문서에 대해 새 작업을 생성하지 않습니다. 이 값을 설정하면
+{@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+ 및 {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} 플래그의 행동을
+재정의합니다(이들 중 하나가 인텐트에서 설정되어 있는 경우). 개요 화면은 앱에 대한 하나의 작업을 표시하고,
+이것이 사용자가 마지막으로 호출한 액티비티가 무엇이든 그것부터 재개합니다.</dd>
+</dl>
+
+<p class="note"><strong>참고:</strong> {@code none} 및 {@code never}를 제외한 다른 값의 경우,
+액티비티를 {@code launchMode="standard"}로 정의해야 합니다. 이 특성을 지정하지 않으면
+{@code documentLaunchMode="none"}이 사용됩니다.</p>
+
+<h2 id="removing">작업 제거</h2>
+
+<p>기본적으로 문서 작업은 해당되는 액티비티가 완료되면 자동으로 개요 화면에서
+제거됩니다. 이 행동을 재정의하려면 {@link android.app.ActivityManager.AppTask} 클래스를 사용합니다. 이때
+{@link android.content.Intent} 플래그 또는 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">
+&lt;activity&gt;</a></code> 특성을 함께 사용하십시오.</p>
+
+<p>개요 화면에서 작업을 완전히 제외하려면 언제든
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+특성, <a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">
+{@code android:excludeFromRecents}</a>를 {@code true}로 설정합니다.</p>
+
+<p>개요 화면에서 앱이 포함할 수 있는 작업의 최대 개수를 설정하려면
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 특성 <a href="{@docRoot}guide/topics/manifest/activity-element.html#maxrecents">{@code android:maxRecents}
+</a>를 정수 값으로 설정합니다. 기본은 16개입니다. 작업의 최대 대수에 도달하면 가장 예전에 사용된 작업이 개요 화면에서
+제거됩니다. {@code android:maxRecents} 최대값은
+50입니다(메모리 용량이 적은 기기에서는 25). 1 미만의 값은 유효하지 않습니다.</p>
+
+<h3 id="#apptask-remove">작업 제거에 AppTask 클래스 사용</h3>
+
+<p>개요 화면에서 새 작업을 생성하는 액티비티에서는 작업을 언제 제거할 것인지와
+그와 관련된 모든 액티비티를 언제 완료할 것인지 지정할 수 있습니다.
+{@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} 메서드를 호출하면 됩니다.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+NewDocumentActivity.java</a></p>
+<pre>
+public void onRemoveFromRecents(View view) {
+ // The document is no longer needed; remove its task.
+ finishAndRemoveTask();
+}
+</pre>
+
+<p class="note"><strong>참고:</strong>
+{@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} 메서드를
+사용하면 {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} 태그 사용을 재정의합니다.
+이 내용은 아래에서 설명합니다.</p>
+
+<h3 id="#retain-finished">완료된 작업 보존</h3>
+
+<p>작업을 개요 화면에 보존하려면(액티비티가 완료되었더라도),
+액티비티를 시작하는 인텐트의 {@link android.content.Intent#addFlags(int) addFlags()} 메서드에 있는
+{@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} 플래그를 전달합니다.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+DocumentCentricActivity.java</a></p>
+<pre>
+private Intent newDocumentIntent() {
+ final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+ android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
+ newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
+ return newDocumentIntent;
+}
+</pre>
+
+<p>같은 효과를 얻기 위해
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 특성 <a href="{@docRoot}guide/topics/manifest/activity-element.html#autoremrecents">
+{@code android:autoRemoveFromRecents}</a>를 {@code false}로 설정해도 됩니다. 기본 값은 문서 액티비티의 경우 {@code true}
+이고, 일반 액티비티의 경우 {@code false}입니다. 이 특성을 사용하면 이전에 논한 것과 같이
+{@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} 플래그를 재정의하게 됩니다.</p>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/ko/guide/components/services.jd b/docs/html-intl/intl/ko/guide/components/services.jd
new file mode 100644
index 000000000000..fb95ea5ed0fa
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/services.jd
@@ -0,0 +1,813 @@
+page.title=서비스
+@jd:body
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>이 문서의 내용</h2>
+<ol>
+<li><a href="#Basics">기본 정보</a></li>
+<ol>
+ <li><a href="#Declaring">매니페스트에서 서비스 선언하기</a></li>
+</ol>
+<li><a href="#CreatingAService">시작된 서비스 생성하기</a>
+ <ol>
+ <li><a href="#ExtendingIntentService">IntentService 클래스 확장하기</a></li>
+ <li><a href="#ExtendingService">서비스 클래스 확장하기</a></li>
+ <li><a href="#StartingAService">서비스 시작</a></li>
+ <li><a href="#Stopping">서비스 중단</a></li>
+ </ol>
+</li>
+<li><a href="#CreatingBoundService">바인딩된 서비스 생성</a></li>
+<li><a href="#Notifications">사용자에게 알림 전송</a></li>
+<li><a href="#Foreground">전경에서 서비스 실행하기</a></li>
+<li><a href="#Lifecycle">서비스 수명 주기 관리</a>
+<ol>
+ <li><a href="#LifecycleCallbacks">수명 주기 콜백 구현하기</a></li>
+</ol>
+</li>
+</ol>
+
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.app.Service}</li>
+ <li>{@link android.app.IntentService}</li>
+</ol>
+
+<h2>샘플</h2>
+<ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code
+ ServiceStartArguments}</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+ LocalService}</a></li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+<li><a href="{@docRoot}guide/components/bound-services.html">바인딩된 서비스</a></li>
+</ol>
+
+</div>
+
+
+<p>{@link android.app.Service}는 배경에서 오래 실행되는 작업을
+수행할 수 있는 애플리케이션 구성 요소이며 사용자 인터페이스를 제공하지 않습니다. 또 다른
+애플리케이션 구성 요소가 서비스를 시작할 수 있으며, 이는 사용자가 또 다른
+애플리케이션으로 전환하더라도 배경에서 계속해서 실행됩니다. 이외에도, 구성 요소를 서비스에 바인딩하여
+서비스와 상호 작용할 수 있으며, 심지어는 프로세스 간 통신(IPC)도 수행할 수 있습니다. 예를 들어 한 서비스는
+네트워크 트랜잭션을 처리하고, 음악을 재생하고 파일 I/O를 수행하거나 콘텐츠 제공자와 상호 작용할 수 있으며
+이 모든 것을 배경에서 수행할 수 있습니다.</p>
+
+<p>서비스는 본질적으로 두 가지 형식을 취합니다.</p>
+
+<dl>
+ <dt>시작됨</dt>
+ <dd>서비스가 "시작된" 상태가 되려면 애플리케이션 구성 요소(예: 액티비티)가
+{@link android.content.Context#startService startService()}를 호출하여 시작하면 됩니다. 서비스는 한 번 시작되고 나면
+배경에서 무기한으로 실행될 수 있으며, 이는 해당 서비스를 시작한 구성 요소가 소멸되었더라도 무관합니다. 보통,
+시작된 서비스는 한 작업을 수행하고 결과를 발신자에게 반환하지 않습니다.
+예를 들어 네트워크에서 파일을 다운로드하거나 업로드할 수 있습니다. 작업을 완료하면, 해당 서비스는
+알아서 중단되는 것이 정상입니다.</dd>
+ <dt>바인딩됨</dt>
+ <dd>서비스가 "바인딩된" 상태가 되려면 애플리케이션 구성 요소가 {@link
+android.content.Context#bindService bindService()}를 사용하여 해당 서비스에 바인딩되면 됩니다. 바인딩된 서비스는 클라이언트-서버
+인터페이스를 제공하여 구성 요소가 서비스와 상호 작용할 수 있도록 해주며, 결과를 가져올 수도 있고 심지어
+이와 같은 작업을 여러 프로세스에 걸쳐 프로세스 간 통신(IPC)으로 수행할 수도 있습니다. 바인딩된 서비스는 또 다른 애플리케이션 구성 요소가
+이에 바인딩되어 있는 경우에만 실행됩니다. 여러 개의 구성 요소가 서비스에 한꺼번에 바인딩될 수 있지만,
+이 모든 것이 바인딩을 해제하면 해당 서비스는 소멸됩니다.</dd>
+</dl>
+
+<p>이 문서는 주로 이러한 두 가지 유형의 서비스를 따로따로 논하지만, 서비스는
+두 가지 방식 모두로 작동할 수 있습니다. 즉 서비스가 시작될 수도 있고(나아가 무기한으로 실행되고) 바인딩도 허용할 수 있다는 뜻입니다.
+이는 그저 두어 가지 콜백 메서드의 구현 여부에 달린 문제입니다. {@link
+android.app.Service#onStartCommand onStartCommand()}를 사용하면 구성 요소가 서비스를 시작할 수 있게 허용하고, {@link
+android.app.Service#onBind onBind()}를 사용하면 바인딩을 허용합니다.</p>
+
+<p>애플리케이션이 시작되었든, 바인딩되었든 아니면 양쪽 모두이든 모든 애플리케이션 구성 요소가
+해당 서비스를 사용할 수 있으며(별도의 애플리케이션에서라도), 이는 어느 구성 요소든 액티비티를
+사용할 수 있는 것과 같습니다. 이를 {@link android.content.Intent}로 시작하면 됩니다. 그러나,
+매니페스트에서 서비스를 비공개로 선언하고 다른 애플리케이션으로부터의 액세스를 차단할 수도 있습니다. 이것은
+<a href="#Declaring">매니페스트에서 서비스
+선언하기</a>에 관한 섹션에서 더 자세히 이야기합니다.</p>
+
+<p class="caution"><strong>주의:</strong> 서비스는 자신의 호스팅 프로세스의
+기본 스레드에서 실행됩니다. 서비스는 자신의 스레드를 직접 생성하지 <strong>않으며</strong>,
+별도의 프로세스에서 실행되지도 <strong>않습니다</strong>(별도로 지정하는 경우는 예외). 이것은 즉,
+서비스가 CPU 집약적인 작업을 수행할 예정이거나 차단적인 작업을 수행할 예정인 경우(예를 들어 MP3
+재생 또는 네트워킹 등), 서비스 내에 새 스레드를 생성하여 해당 작업을 수행하도록 해야 한다는 뜻입니다. 별도의 스레드를 사용하면
+'애플리케이션이 응답하지 않습니다(ANR)' 오류가 일어날 위험을 줄일 수 있으며
+애플리케이션의 기본 스레드는 액티비티와 사용자 상호 작용 전용으로 유지될 수 있습니다.</p>
+
+
+<h2 id="Basics">기본 정보</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>서비스와 스레드 중 어느 것을 사용해야 할까요?</h3>
+ <p>서비스는 그저 배경에서 실행될 수 있는 구성 요소일 뿐입니다. 이는 사용자가
+애플리케이션과 상호 작용하지 않아도 관계 없이 해당됩니다. 따라서, 서비스를 생성하는 것은 꼭 그것이 필요할 때만으로 국한되어야
+합니다.</p>
+ <p>기본 스레드 외부에서 작업을 수행해야 하지만 사용자가 애플리케이션과 상호 작용 중인
+동안에만 수행하면 되는 경우라면, 서비스가 아니라 그 대신 새 스레드를 생성해야 합니다. 예를 들어
+액티비티가 실행되는 중에만 음악을 재생하고자 하는 경우,
+{@link android.app.Activity#onCreate onCreate()} 안에 스레드를 생성하고 이를 {@link
+android.app.Activity#onStart onStart()}에서 실행하기 시작한 다음 {@link android.app.Activity#onStop
+onStop()}에서 중단하면 됩니다. 또한, 기존의 {@link java.lang.Thread} 클래스 대신
+{@link android.os.AsyncTask} 또는 {@link android.os.HandlerThread}를 사용하는 방안도 고려하십시오. 스레드에 관한 자세한 정보는 <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">프로세스 및
+스레딩</a> 문서를 참조하십시오.</p>
+ <p>서비스를 사용하는 경우 기본적으로 애플리케이션의 기본 스레드에서
+계속 실행되므로 서비스가 집약적이거나 차단적인 작업을 수행하는 경우 여전히 서비스 내에
+새 스레드를 생성해야 한다는 점을 명심하십시오.</p>
+</div>
+</div>
+
+<p>서비스를 생성하려면 {@link android.app.Service}의 하위 클래스를 생성해야 합니다(아니면 이의
+기존 하위 클래스 중 하나). 구현에서는 서비스 수명 주기의 주요 측면을 처리하는 콜백 메서드를
+몇 가지 재정의해야 하며 서비스에 바인딩할 구성 요소에 대한 메커니즘을
+제공해야 합니다(해당되는 경우). 재정의해야 하는 가장 중요한 콜백 메서드는 다음과 같습니다.</p>
+
+<dl>
+ <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 또 다른 구성 요소(예: 액티비티)가 서비스를
+시작하도록 요청하는 경우입니다. 이때 {@link android.content.Context#startService
+startService()}를 호출하는 방법을 씁니다. 이 메서드가 실행되면 서비스가 시작되고 배경에서 무기한으로 실행될 수
+있습니다. 이것을 구성하면 서비스의 작업이 완료되었을 때 해당 서비스를 중단하는 것은
+개발자 본인의 책임입니다. 이때 {@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()}를 호출하면 됩니다 (바인딩만 제공하고자 하는 경우, 이 메서드를 구현하지
+않아도 됩니다).</dd>
+ <dt>{@link android.app.Service#onBind onBind()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 또 다른 구성 요소가 해당 서비스에 바인딩되고자 하는 경우
+(예를 들어 RPC를 수행하기 위해)입니다. 이때 {@link android.content.Context#bindService
+bindService()}를 호출하는 방법을 씁니다. 이 메서드를 구현할 때에는 클라이언트가 서비스와 통신을 주고받기 위해 사용할
+인터페이스를 제공해야 합니다. 이때 {@link android.os.IBinder}를 반환하면 됩니다. 이 메서드는 항상
+구현해야 하지만, 바인딩을 허용하지 않고자 하면 null을 반환해야 합니다.</dd>
+ <dt>{@link android.app.Service#onCreate()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 서비스가 처음 생성되어 일회성 설정
+절차를 수행하는 경우입니다({@link android.app.Service#onStartCommand onStartCommand()} 또는
+{@link android.app.Service#onBind onBind()}를 호출하기 전에). 서비스가 이미 실행 중인 경우, 이 메서드는 호출되지
+않습니다.</dd>
+ <dt>{@link android.app.Service#onDestroy()}</dt>
+ <dd>시스템이 이 메서드를 호출하는 것은 해당 서비스를 더 이상 사용하지 않고 소멸시키는 경우입니다.
+서비스에 이것을 구현해야 스레드, 등록된 각종 수신기(listener, receiver) 등
+모든 리소스를 정리할 수 있습니다. 이것이 서비스가 수신하는 마지막 호출입니다.</dd>
+</dl>
+
+<p>한 구성 요소가 {@link
+android.content.Context#startService startService()}를 호출하여 서비스를 시작하면({@link
+android.app.Service#onStartCommand onStartCommand()}로의 호출을 초래함), 해당 서비스는
+알아서 {@link android.app.Service#stopSelf()}로 스스로를 중단할 때까지 또는
+또 다른 구성 요소가 {@link android.content.Context#stopService stopService()}를 호출하여 서비스를 중단시킬 때까지 실행 중인 상태로 유지됩니다.</p>
+
+<p>한 구성 요소가
+{@link android.content.Context#bindService bindService()}를 호출하여 서비스를 생성하는 경우(그리고 {@link
+android.app.Service#onStartCommand onStartCommand()}를 호출하지 <em>않은</em> 경우), 해당 서비스는
+해당 구성 요소가 바인딩되어 있는 경우에만 실행됩니다. 서비스가 모든 클라이언트로부터 바인딩 해제되면 시스템이 이를
+소멸시킵니다.</p>
+
+<p>Android 시스템이 서비스를 강제 중단시키는 것은 메모리가 부족하여 사용자가 초점을 집중하고 있는
+액티비티를 위해 시스템 리소스를 회복해야만 하는 경우로만 국한됩니다. 해당 서비스가 사용자의 주목을
+끌고 있는 액티비티에 바인딩되어 있다면 중단될 가능성이 낮고, 서비스가 <a href="#Foreground">전경에서 실행</a>된다고 선언된 경우(나중에 자세히 논함), 거의 절대 중단되지 않습니다.
+그렇지 않으면, 서비스가 시작되었고 오랫동안 실행되는 경우
+시간이 지나면서 시스템이 배경 작업 목록에서의 이 서비스의 위치를 점점 낮추고
+서비스는 중단되기 매우 쉬워집니다. 서비스가 시작되었다면 이를 시스템에 의한 재시작을 정상적으로
+처리하도록 디자인해야 합니다. 시스템이 서비스를 중단시키는 경우, 리소스를 다시 사용할 수 있게 되면
+시스템이 가능한 한 빨리 이를 다시 시작합니다(다만 이것은 개발자가 {@link
+android.app.Service#onStartCommand onStartCommand()}에서 반환하는 값에도 좌우됩니다. 이 내용은 나중에 논합니다). 시스템이 서비스를
+소멸시킬 수 있는 경우에 대한 자세한 정보는 <a href="{@docRoot}guide/components/processes-and-threads.html">프로세스 및 스레딩</a>
+문서를 참조하십시오.</p>
+
+<p>다음 섹션에서는 각 유형의 서비스를 생성하는 방법과 다른 애플리케이션 구성 요소에서
+이를 사용하는 방법을 배우게 됩니다.</p>
+
+
+
+<h3 id="Declaring">매니페스트에서 서비스 선언하기</h3>
+
+<p>액티비티(및 다른 구성 요소)와 마찬가지로, 서비스는 모두 애플리케이션의 매니페스트
+파일에서 선언해야 합니다.</p>
+
+<p>서비스를 선언하려면 <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> 요소를
+<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+ 요소의 하위로 추가하면 됩니다. 예:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ ...
+ &lt;application ... &gt;
+ &lt;service android:name=".ExampleService" /&gt;
+ ...
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+<p>매니페스트에서 서비스를 선언하는 데 대한 자세한 정보는 <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a>
+요소 참조를 확인하십시오.</p>
+
+<p><a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> 요소에 포함시킬 수 있는 다른 속성도 있습니다.
+이를 포함시켜 서비스를 시작하는 데 필요한 권한과 서비스가 실행되어야 하는 프로세스 등의
+속성을 정의할 수 있습니다. <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a>
+속성이 유일한 필수 속성입니다. 이것은 서비스의 클래스 이름을 나타냅니다. 일단 애플리케이션을
+게시하고 나면 이 이름을 변경해서는 안 됩니다. 이름을 변경하면
+서비스를 시작하거나 바인딩할 명시적 인텐트에 대한 종속성으로 인해 코드를 단절시킬 위험이 있기 때문입니다(블로그 게시물의 <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">
+바꿀 수 없는 항목</a>을 참조하십시오).
+
+<p>앱의 보안을 보장하려면 <strong>
+{@link android.app.Service}을 시작하거나 바인딩할 때 항상 명시적 인텐트를 사용하고</strong> 서비스에 대한 인텐트 필터는 선언하지 마십시오. 어느
+서비스를 시작할지 어느 정도 모호성을 허용하는 것이 중요한 경우, 서비스에 대해
+인텐트 필터를 제공하고 구성 요소 이름을 {@link
+android.content.Intent}에서 배제할 수 있지만, 그러면 해당 인텐트에 대한 패키지를 {@link
+android.content.Intent#setPackage setPackage()}로 설정하여 대상 서비스에 대해 충분한 명확화를
+제공하도록 해야 합니다.</p>
+
+<p>이외에도 서비스를 본인의 앱에만 사용 가능하도록 보장할 수도 있습니다.
+<a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
+ 속성을 포함시킨 뒤 이를 {@code "false"}로 설정하면 됩니다. 이렇게 하면 다른 앱이 여러분의 서비스를 시작하지 못하도록 효과적으로 방지해주며,
+이는 명시적 인텐트를 사용하는 경우에도 문제 없이 적용됩니다.</p>
+
+
+
+
+<h2 id="CreatingStartedService">시작된 서비스 생성하기</h2>
+
+<p>시작된 서비스란 다른 구성 요소가 {@link
+android.content.Context#startService startService()}를 호출하여 시작하고, 그 결과 서비스의
+{@link android.app.Service#onStartCommand onStartCommand()} 메서드를 호출하는 결과를 초래한 것을 말합니다.</p>
+
+<p>서비스가 시작되면 이를 시작한 구성 요소와 독립된 자신만의
+수명 주기를 가지며 해당 서비스는 배경에서 무기한으로 실행될 수 있습니다. 이는 해당 서비스를
+시작한 구성 요소가 소멸되었더라도 무관합니다. 따라서, 서비스는 작업이 완료되면
+{@link android.app.Service#stopSelf stopSelf()}를 호출하여 스스로 알아서 중단되는 것이 정상이며 아니면 다른 구성 요소가
+{@link android.content.Context#stopService stopService()}를 호출하여 중단시킬 수도 있습니다.</p>
+
+<p>애플리케이션 구성 요소(예: 액티비티)가 서비스를 시작하려면 {@link
+android.content.Context#startService startService()}를 호출하고, {@link android.content.Intent}를
+전달하면 됩니다. 이것은 서비스를 나타내고 서비스가 사용할 모든 데이터를 포함합니다. 서비스는 이
+{@link android.content.Intent}를 {@link android.app.Service#onStartCommand
+onStartCommand()} 메서드에서 수신합니다.</p>
+
+<p>예를 들어 어느 액티비티가 온라인 데이터베이스에 데이터를 약간 저장해야 한다고 가정합니다. 액티비티가
+동반자 서비스를 시작하여 저장할 데이터를 이에 전달할 수 있습니다. 이때 인텐트를 {@link
+android.content.Context#startService startService()}에 전달하면 됩니다. 서비스는 이 인텐트를 {@link
+android.app.Service#onStartCommand onStartCommand()}에서 수신하고 인터넷에 연결한 다음 데이터베이스
+트랜잭션을 수행합니다. 작업을 완료하면, 해당 서비스는 알아서 스스로 중단되고
+소멸됩니다.</p>
+
+<p class="caution"><strong>주의:</strong> 서비스는 기본적으로 자신이 선언된 애플리케이션의 같은
+프로세스에서 실행되기도 하고 해당 애플리케이션의 기본 스레드에서 실행되기도 합니다. 따라서, 사용자가
+같은 애플리케이션의 액티비티와 상호 작용하는 동안 서비스가 집약적이거나 차단적인 작업을 수행하는 경우,
+해당 서비스 때문에 액티비티 성능이 느려지게 됩니다. 애플리케이션 성능에 영향을 미치는 것을 방지하려면,
+서비스 내에서 새 스레드를 시작해야 합니다.</p>
+
+<p>기존에는 시작된 서비스를 생성하기 위해 확장할 수 있는 클래스가 두 개 있었습니다.</p>
+<dl>
+ <dt>{@link android.app.Service}</dt>
+ <dd>이것이 모든 서비스의 기본 클래스입니다. 이 클래스를 확장하는 경우, 서비스의 모든 작업을 수행할
+새 스레드를 만드는 것이 중요합니다. 서비스가 기본적으로 애플리케이션의 기본 스레드를 사용하기
+때문인데, 이로 인해 애플리케이션이 실행 중인 모든 액티비티의 성능이
+느려질 수 있기 때문입니다.</dd>
+ <dt>{@link android.app.IntentService}</dt>
+ <dd>이것은 {@link android.app.Service}의 하위 클래스로, 작업자 스레드를
+사용하여 모든 시작 요청을 처리하되 한 번에 하나씩 처리합니다. 서비스가 여러 개의 요청을
+동시에 처리하지 않아도 되는 경우 이것이 최선의 옵션입니다. 해야 할 일은 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}를 구현하는 것뿐으로, 이것이 각 시작 요청에 대한 인텐트를 수신하여
+개발자는 배경 작업을 수행할 수 있습니다.</dd>
+</dl>
+
+<p>다음 섹션에서는 이와 같은 클래스 중 하나를 사용하여 서비스를 구현하는 방법을
+설명합니다.</p>
+
+
+<h3 id="ExtendingIntentService">IntentService 클래스 확장하기</h3>
+
+<p>대부분의 시작된 서비스는 여러 개의 요청을 동시에 처리하지 않아도 되기 때문에
+(이는 사실 위험한 다중 스레딩 시나리오일 수 있습니다), 서비스를 구현할 때에는
+{@link android.app.IntentService} 클래스를 사용하는 것이 최선의 방안일 것입니다.</p>
+
+<p>{@link android.app.IntentService}는 다음과 같은 작업을 수행합니다.</p>
+
+<ul>
+ <li>애플리케이션의 기본 스레드와는 별도로 {@link
+android.app.Service#onStartCommand onStartCommand()}에 전달된 모든 인텐트를 실행하는 기본 작업자 스레드를
+생성합니다.</li>
+ <li>한 번에 인텐트를 하나씩 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} 구현에 전달하는 작업 대기열을 생성하므로 다중 스레딩에 대해 염려할 필요가
+전혀 없습니다.</li>
+ <li>시작 요청이 모두 처리된 후 서비스를 중단하므로 개발자가
+{@link android.app.Service#stopSelf}를 호출할 필요가 전혀 없습니다.</li>
+ <li>{@link android.app.IntentService#onBind onBind()}의 기본 구현을 제공하여 null을
+반환하도록 합니다.</li>
+ <li>{@link android.app.IntentService#onStartCommand
+onStartCommand()}의 기본 구현을 제공하여 인텐트를 작업 대기열에 보내고, 다음으로 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} 구현에 보내도록 합니다.</li>
+</ul>
+
+<p>이 모든 것은 결론적으로 개발자가 직접 할 일은 클라이언트가 제공한 작업을 수행할 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}를 구현하는 것뿐이라는 사실로
+이어집니다. (다만, 서비스에 대해 작은 생성자를 제공해야 하기도 합니다.)</p>
+
+<p>다음은 {@link android.app.IntentService}의 구현을 예시로 나타낸 것입니다.</p>
+
+<pre>
+public class HelloIntentService extends IntentService {
+
+ /**
+ * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
+ * constructor with a name for the worker thread.
+ */
+ public HelloIntentService() {
+ super("HelloIntentService");
+ }
+
+ /**
+ * The IntentService calls this method from the default worker thread with
+ * the intent that started the service. When this method returns, IntentService
+ * stops the service, as appropriate.
+ */
+ &#64;Override
+ protected void onHandleIntent(Intent intent) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() &lt; endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+}
+</pre>
+
+<p>필요한 것은 이게 전부입니다. 생성자 하나와 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} 구현뿐이죠.</p>
+
+<p>다른 콜백 메서드도 재정의하기로 결정하는 경우-예를 들어 {@link
+android.app.IntentService#onCreate onCreate()}, {@link
+android.app.IntentService#onStartCommand onStartCommand()} 또는 {@link
+android.app.IntentService#onDestroy onDestroy()}-슈퍼 구현을 꼭 호출해야 합니다.
+그래야 {@link android.app.IntentService}가 작업자 스레드의 수명을 적절하게 처리할 수 있습니다.</p>
+
+<p>예를 들어 {@link android.app.IntentService#onStartCommand onStartCommand()}는 반드시
+기본 구현을 반환해야 합니다(이로써 인텐트가 {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}로 전달되는 것입니다).</p>
+
+<pre>
+&#64;Override
+public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+ return super.onStartCommand(intent,flags,startId);
+}
+</pre>
+
+<p>{@link android.app.IntentService#onHandleIntent onHandleIntent()} 외에 슈퍼 클래스를
+호출하지 않아도 되는 유일한 메서드는 {@link android.app.IntentService#onBind
+onBind()}입니다(다만 이를 구현하는 것은 서비스가 바인딩을 허용할 때에만 필요합니다).</p>
+
+<p>다음 섹션에서는 기본 {@link android.app.Service}
+클래스를 확장할 때 같은 종류의 서비스를 구현하는 방법을 배우게 됩니다. 이때에는 코드가 훨씬 많이 필요하지만,
+동시 시작 요청을 처리해야 하는 경우 이것이 적절할 수 있습니다.</p>
+
+
+<h3 id="ExtendingService">서비스 클래스 확장하기</h3>
+
+<p>이전 섹션에서 본 것과 같이 {@link android.app.IntentService}를 사용하면
+시작된 서비스 구현이 매우 단순해집니다. 하지만 서비스가 다중 스레딩을
+수행해야 하는 경우(작업 대기열을 통해 시작 요청을 처리하는 대신), 그때는
+{@link android.app.Service} 클래스를 확장하여 각 인텐트를 처리하게 할 수 있습니다.</p>
+
+<p>비교를 위해 다음 예시의 코드를 보겠습니다. 이는 {@link
+android.app.Service} 클래스의 구현으로, 위의 예시에서 {@link
+android.app.IntentService}를 사용하여 수행한 것과 똑같은 작업을 수행합니다. 바꿔 말하면 각 시작 요청에 대해
+작업자 스레드를 사용하여 작업을 수행하고 한 번에 요청을 하나씩만 처리한다는 뜻입니다.</p>
+
+<pre>
+public class HelloService extends Service {
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+
+ // Handler that receives messages from the thread
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+ &#64;Override
+ public void handleMessage(Message msg) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() &lt; endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ // Stop the service using the startId, so that we don't stop
+ // the service in the middle of handling another job
+ stopSelf(msg.arg1);
+ }
+ }
+
+ &#64;Override
+ public void onCreate() {
+ // Start up the thread running the service. Note that we create a
+ // separate thread because the service normally runs in the process's
+ // main thread, which we don't want to block. We also make it
+ // background priority so CPU-intensive work will not disrupt our UI.
+ HandlerThread thread = new HandlerThread("ServiceStartArguments",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+
+ // Get the HandlerThread's Looper and use it for our Handler
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper);
+ }
+
+ &#64;Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+
+ // For each start request, send a message to start a job and deliver the
+ // start ID so we know which request we're stopping when we finish the job
+ Message msg = mServiceHandler.obtainMessage();
+ msg.arg1 = startId;
+ mServiceHandler.sendMessage(msg);
+
+ // If we get killed, after returning from here, restart
+ return START_STICKY;
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ // We don't provide binding, so return null
+ return null;
+ }
+
+ &#64;Override
+ public void onDestroy() {
+ Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
+ }
+}
+</pre>
+
+<p>보시다시피 {@link android.app.IntentService}를 사용할 때보다 훨씬 손이 많이 갑니다.</p>
+
+<p>그러나, 각 호출을 {@link android.app.Service#onStartCommand
+onStartCommand()}로 직접 처리할 수 있기 때문에 여러 개의 요청을 동시에 수행할 수 있습니다. 이 예시는 그것을
+보여주는 것은 아니지만, 그런 작업을 원하는 경우 각 요청에 대해 새 스레드를
+하나씩 생성한 다음 곧바로 실행하면 됩니다(이전 요청이 끝날 때까지 기다리는 대신).</p>
+
+<p>{@link android.app.Service#onStartCommand onStartCommand()} 메서드가 반드시
+정수를 반환해야 한다는 사실을 유의하십시오. 정수는 시스템이 서비스를 중단시킨 경우 시스템이 해당 서비스를
+계속하는 방법에 대해 설명하는 값입니다(위에서 논한 바와 같이 {@link
+android.app.IntentService}의 기본 구현이 이것을 개발자 대신 처리해줍니다. 개발자가 이를 수정할 수도 있습니다).
+{@link android.app.Service#onStartCommand onStartCommand()}로부터의 반환 값은 반드시
+다음 상수 중 하나여야 합니다.</p>
+
+<dl>
+ <dt>{@link android.app.Service#START_NOT_STICKY}</dt>
+ <dd>시스템이 서비스를 {@link android.app.Service#onStartCommand
+onStartCommand()} 반환 후에 중단시키면 서비스를 재생성하면 <em>안 됩니다.</em> 다만 전달할
+보류 인텐트가 있는 경우는 예외입니다. 이것은 서비스가 불필요하게 실행되는 일을 피할 수 있는 가장 안전한 옵션이며,
+애플리케이션이 완료되지 않은 모든 작업을 단순히 재시작할 수 있을 때 좋습니다.</dd>
+ <dt>{@link android.app.Service#START_STICKY}</dt>
+ <dd>시스템이 서비스를 {@link android.app.Service#onStartCommand
+onStartCommand()} 반환 후에 중단시키는 경우, 서비스를 재생성하고 {@link
+android.app.Service#onStartCommand onStartCommand()}를 호출하되 마지막 인텐트를 다시 전달하지는 <em>마십시오.</em>
+그 대신, 시스템이 null 인텐트로 {@link android.app.Service#onStartCommand onStartCommand()}를
+호출합니다. 다만 서비스를 시작할 보류 인텐트가 있는 경우만은 예외이며, 이럴 때에는
+그러한 인텐트를 전달합니다. 이것은 명령을 실행하지는 않지만 무기한으로 실행 중이며 작업을 기다리고 있는
+미디어 플레이어(또는 그와 비슷한 서비스)에 적합합니다.</dd>
+ <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
+ <dd>시스템이 서비스를 {@link android.app.Service#onStartCommand
+onStartCommand()} 반환 후에 중단시키는 경우, 서비스를 재생성하고 서비스에 전달된 마지막 인텐트로 {@link
+android.app.Service#onStartCommand onStartCommand()}를
+호출하십시오. 모든 보류 인텐트가 차례로 전달됩니다. 이것은 즉시 재개되어야 하는 작업을
+능동적으로 수행 중인 서비스(예를 들어 파일 다운로드 등)에 적합합니다.</dd>
+</dl>
+<p>이러한 반환 값에 대한 자세한 내용은 각 상수에 대해 링크로 연결된 참조 문서를
+확인하십시오.</p>
+
+
+
+<h3 id="StartingAService">서비스 시작</h3>
+
+<p>액티비티나 다른 구성 요소에서 서비스를 시작하려면
+{@link android.content.Intent}를(시작할 서비스를 나타냄) {@link
+android.content.Context#startService startService()}에 전달하면 됩니다. Android 시스템이 서비스의 {@link
+android.app.Service#onStartCommand onStartCommand()} 메서드를 호출하여 여기에 {@link
+android.content.Intent}를 전달합니다. ({@link android.app.Service#onStartCommand
+onStartCommand()}를 직접 호출하면 절대로 안 됩니다.)</p>
+
+<p>예를 들어 이전 섹션의 예시 서비스({@code
+HelloService})를 액티비티가 시작하려면 {@link android.content.Context#startService
+startService()}로 명시적 인텐트를 사용하면 됩니다.</p>
+
+<pre>
+Intent intent = new Intent(this, HelloService.class);
+startService(intent);
+</pre>
+
+<p>{@link android.content.Context#startService startService()} 메서드가 즉시 반환되며
+Android 시스템이 서비스의 {@link android.app.Service#onStartCommand
+onStartCommand()} 메서드를 호출합니다. 서비스가 이미 실행 중이지 않은 경우, 시스템은 우선 {@link
+android.app.Service#onCreate onCreate()}를 호출하고, 다음으로 {@link android.app.Service#onStartCommand
+onStartCommand()}를 호출합니다.</p>
+
+<p>서비스가 바인딩도 제공하지 않는 경우, {@link
+android.content.Context#startService startService()}와 함께 전달된 인텐트가 애플리케이션 구성 요소와 서비스 사이의
+유일한 통신 방법입니다. 그러나 서비스가 결과를 돌려보내기를 원하는 경우, 서비스를 시작한
+클라이언트가 브로드캐스트를 위해 {@link android.app.PendingIntent}를
+만들 수 있고({@link android.app.PendingIntent#getBroadcast getBroadcast()} 사용) 이를 서비스를 시작한
+{@link android.content.Intent} 내의 서비스에 전달할 수 있습니다. 그러면 서비스가
+이 브로드캐스트를 사용하여 결과를 전달할 수 있게 됩니다.</p>
+
+<p>서비스를 시작하기 위한 여러 개의 요청은 서비스의
+{@link android.app.Service#onStartCommand onStartCommand()}로의 상응하는 여러 개의 호출이라는 결과를 낳습니다. 하지만, 서비스를 중단하려면
+이를 중단하라는 요청 하나({@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()} 사용)만 있으면 됩니다.</p>
+
+
+<h3 id="Stopping">서비스 중단</h3>
+
+<p>시작된 서비스는 자신만의 수명 주기를 직접 관리해야 합니다. 다시 말해, 시스템이
+서비스를 중단하거나 소멸시키지 않는다는 뜻입니다. 다만 시스템 메모리를 회복해야 하고 서비스가
+{@link android.app.Service#onStartCommand onStartCommand()} 반환 후에도 계속 실행되는 경우는 예외입니다. 따라서,
+서비스는 {@link android.app.Service#stopSelf stopSelf()}를 호출하여 스스로 중단시켜야 하고, 아니면
+다른 구성 요소가 {@link android.content.Context#stopService stopService()}를 호출하여 이를 중단시킬 수 있습니다.</p>
+
+<p>일단 {@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()}로 중단하기를 요청하고 나면 시스템이 서비스를 가능한 한 빨리
+소멸시킵니다.</p>
+
+<p>그러나, 서비스가 {@link
+android.app.Service#onStartCommand onStartCommand()}로의 요청을 동시에 여러 개 처리하기를 바라는 경우라면 시작 요청 처리를 완료한 뒤에도
+서비스를 중단하면 안 됩니다. 그 이후 새 시작 요청을 받았을 수 있기
+때문입니다(첫 요청 종료 시에 중단하면 두 번째 요청을 종료시킵니다). 이 문제를
+피하려면, {@link android.app.Service#stopSelf(int)}를 사용하여 서비스를
+중단시키라는 개발자의 요청이 항상 최신 시작 요청에 기반하도록 해야 합니다. 다시 말해, {@link
+android.app.Service#stopSelf(int)}를 호출할 때면 시작 요청의 ID({@link android.app.Service#onStartCommand onStartCommand()}에 전달된
+<code>startId</code>)를 전달하게 됩니다. 여기에 중단 요청이
+부합됩니다. 그런 다음 개발자가 {@link
+android.app.Service#stopSelf(int)}를 호출할 수 있기 전에 서비스가 새 시작 요청을 받은 경우, ID가 일치하지 않게 되고 서비스는 중단되지 않습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 서비스가 작업을 완료한 다음 애플리케이션이
+소속 서비스를 중단할 수 있어야 한다는 점이 중요합니다. 그래야 시스템 리소스 낭비를 피하고 배터리 전력 소모를 줄일 수 있습니다. 필요한 경우
+다른 구성 요소도 서비스를 중단시킬 수 있습니다. {@link
+android.content.Context#stopService stopService()}를 호출하면 됩니다. 서비스에 대해 바인딩을 활성화하더라도,
+서비스가 {@link
+android.app.Service#onStartCommand onStartCommand()}로의 호출을 한 번이라도 받았으면 항상 서비스를 직접 중단시켜야 합니다.</p>
+
+<p>서비스의 수명 주기에 대한 자세한 정보는 아래에 있는 <a href="#Lifecycle">서비스 수명 주기 관리</a>에 관한 섹션을 참고하세요.</p>
+
+
+
+<h2 id="CreatingBoundService">바인딩된 서비스 생성</h2>
+
+<p>바인딩된 서비스는 애플리케이션 구성 요소가 자신에게 바인딩될 수 있도록 허용하는 서비스로, 이때 {@link
+android.content.Context#bindService bindService()}를 호출하여 오래 지속되는 연결을 생성합니다
+(또한 보통은 구성 요소가 {@link
+android.content.Context#startService startService()}를 호출하여 서비스를 <em>시작</em>하는 것을 허용하지 않습니다).</p>
+
+<p>액티비티와 애플리케이션의 다른 구성 요소에서 서비스와 상호 작용하기를 원하는 경우
+바인딩된 서비스를 생성해야 합니다. 아니면 애플리케이션의 기능 몇 가지를 프로세스 간 통신(IPC)을 통해
+다른 애플리케이션에 노출하고자 하는 경우에도 좋습니다.</p>
+
+<p>바인딩된 서비스를 생성하려면 {@link
+android.app.Service#onBind onBind()} 콜백 메서드를 구현하여 서비스와의 통신을 위한 인터페이스를 정의하는
+{@link android.os.IBinder}를 반환하도록 해야 합니다. 그러면 다른 애플리케이션 구성 요소가
+{@link android.content.Context#bindService bindService()}를 호출하여 해당 인터페이스를 검색하고, 서비스에 있는 메서드를
+호출하기 시작할 수 있습니다. 서비스는 자신에게 바인딩된 애플리케이션 구성 요소에게 도움이 되기 위해서만
+존재하는 것이므로, 서비스에 바인딩된 구성 요소가 없으면 시스템이 이를 소멸시킵니다(바인딩된 서비스는 시작된 서비스처럼
+{@link android.app.Service#onStartCommand onStartCommand()}를 통해
+중단시키지 <em>않아도</em> 됩니다).</p>
+
+<p>바인딩된 서비스를 생성하려면 가장 먼저 해야 할 일은 클라이언트가 서비스와
+통신할 수 있는 방법을 나타내는 인터페이스를 정의하는 것입니다. 서비스와 클라이언트 사이에서 쓰이는 이 인터페이스는
+반드시 {@link android.os.IBinder}의 구현이어야 하며 이를
+서비스가 {@link android.app.Service#onBind
+onBind()} 콜백 메서드에서 반환해야 합니다. 클라이언트가 {@link android.os.IBinder}를 수신하면 해당 인터페이스를 통해 서비스와
+상호 작용을 시작할 수 있습니다.</p>
+
+<p>여러 클라이언트가 서비스에 한꺼번에 바인딩될 수 있습니다. 클라이언트가 서비스와의 상호 작용을 완료하면 이는
+{@link android.content.Context#unbindService unbindService()}를 호출하여 바인딩을 해제합니다. 서비스에
+바인딩된 클라이언트가 하나도 없으면 시스템이 해당 서비스를 소멸시킵니다.</p>
+
+<p>바인딩된 서비스를 구현하는 데에는 여러 가지 방법이 있으며 그러한 구현은 시작된 서비스보다
+훨씬 복잡합니다. 따라서 바인딩된 서비스 논의는
+<a href="{@docRoot}guide/components/bound-services.html">바인딩된 서비스</a>에 관한 별도의 문서에서 다룹니다.</p>
+
+
+
+<h2 id="Notifications">사용자에게 알림 전송</h2>
+
+<p>서비스는 일단 실행되고 나면 사용자에게 <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">알림 메시지</a> 또는 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">상태 표시줄 알림</a> 등을 사용해 이벤트를 알릴 수 있습니다.</p>
+
+<p>알림 메시지란 현재 창의 표면에 잠시 나타났다가 사라지는 메시지이고,
+상태 표시줄 알림은 상태 표시줄에 메시지가 담긴 아이콘을 제공하여 사용자가 이를 선택하여
+조치를 취할 수 있게 하는 것입니다(예: 액티비티 시작).</p>
+
+<p>보통, 일종의 배경 작업이 완료되었고
+(예: 파일 다운로드 완료) 이제 사용자가 그에 대해 조치를 취할 수 있는 경우 상태 표시줄 알림이
+최선의 기법입니다. 사용자가 확장된 보기에서 알림을 선택하면,
+해당 알림이 액티비티를 시작할 수 있습니다(예: 다운로드한 파일 보기).</p>
+
+<p>자세한 정보는 <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">알림 메시지</a> 또는 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">상태 표시줄 알림</a>
+개발자 가이드를 참조하십시오.</p>
+
+
+
+<h2 id="Foreground">전경에서 서비스 실행하기</h2>
+
+<p>전경 서비스는 사용자가 능동적으로 인식하고 있으므로 메모리 부족 시에도
+시스템이 중단할 후보로 고려되지 않는 서비스를 말합니다. 전경
+서비스는 상태 표시줄에 대한 알림을 제공해야 합니다. 이것은
+"진행 중" 제목 아래에 배치되며, 이는 곧 해당 알림은 서비스가 중단되었거나
+전경에서 제거되지 않은 이상 무시할 수 없다는 뜻입니다.</p>
+
+<p>예를 들어 서비스에서 음악을 재생하는 음악 플레이어는 전경에서
+실행되도록 설정해야 합니다. 사용자가 이것의 작동을 분명히 인식하고 있기
+때문입니다. 상태 표시줄에 있는 알림은 현재 노래를 나타내고
+사용자로 하여금 음악 플레이어와 상호 작용할 액티비티를 시작하게 해줄 수도 있습니다.</p>
+
+<p>서비스가 전경에서 실행되도록 요청하려면 {@link
+android.app.Service#startForeground startForeground()}를 호출하면 됩니다. 이 메서드는 두 개의 매개변수를 취합니다.
+그 중 하나는 해당 알림을 고유하게 식별하는 정수이고 다른 하나는 상태 표시줄에 해당되는 {@link
+android.app.Notification}입니다. 예:</p>
+
+<pre>
+Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
+ System.currentTimeMillis());
+Intent notificationIntent = new Intent(this, ExampleActivity.class);
+PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+notification.setLatestEventInfo(this, getText(R.string.notification_title),
+ getText(R.string.notification_message), pendingIntent);
+startForeground(ONGOING_NOTIFICATION_ID, notification);
+</pre>
+
+<p class="caution"><strong>주의:</strong> {@link
+android.app.Service#startForeground startForeground()}에 부여하는 정수 ID가 0이면 안 됩니다.</p>
+
+
+<p>서비스를 전경에서 제거하려면 {@link
+android.app.Service#stopForeground stopForeground()}를 호출하면 됩니다. 이 메서드는 부울 값을 취하며, 이것이
+상태 표시줄 알림도 제거할지 여부를 나타냅니다. 이 메서드는 서비스를 중단시키지 <em>않습니다</em>.
+ 그러나, 서비스가 전경에서 실행 중인 동안 서비스를 중단시키면
+알림도 마찬가지로 제거됩니다.</p>
+
+<p>알림에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">상태 표시줄
+알림 생성</a>을 참조하십시오.</p>
+
+
+
+<h2 id="Lifecycle">서비스 수명 주기 관리</h2>
+
+<p>서비스의 수명 주기는 액티비티의 수명 주기보다 훨씬 간단합니다. 하지만, 서비스를 생성하고
+소멸시키는 방법에 특히 주의를 기울여야 한다는 면에서 중요도는 이쪽이 더 높습니다. 서비스는 사용자가 모르는 채로
+배경에서 실행될 수 있기 때문입니다.</p>
+
+<p>서비스 수명 주기&mdash;생성되었을 때부터 소멸될 때까지&mdash;는 두 가지 서로 다른 경로를
+따를 수 있습니다.</p>
+
+<ul>
+<li>시작된 서비스
+ <p>서비스는 또 다른 구성 요소가 {@link
+android.content.Context#startService startService()}를 호출하면 생성됩니다. 그러면 서비스가 무기한으로 실행될 수 있으며
+스스로 알아서 중단되어야 합니다. 이때 {@link
+android.app.Service#stopSelf() stopSelf()}를 호출하는 방법을 씁니다. 또 다른 구성 요소도 서비스를 중단시킬 수
+있습니다. {@link android.content.Context#stopService
+stopService()}를 호출하면 됩니다. 서비스가 중단되면 시스템이 이를 소멸시킵니다.</p></li>
+
+<li>바인딩된 서비스
+ <p>서비스는 또 다른 구성 요소(클라이언트)가 {@link
+android.content.Context#bindService bindService()}를 호출하면 생성됩니다. 그러면 클라이언트가
+{@link android.os.IBinder} 인터페이스를 통해 서비스와 통신을 주고받을 수 있습니다. 클라이언트가 연결을 종료하려면
+{@link android.content.Context#unbindService unbindService()}를 호출하면 됩니다. 여러 클라이언트가 같은 서비스에
+바인딩될 수 있으며, 이 모두가 바인딩을 해제하면 시스템이 해당 서비스를 소멸시킵니다 (서비스가 스스로를 중단시키지
+<em>않아도</em> 됩니다).</p></li>
+</ul>
+
+<p>이와 같은 두 가지 경로는 완전히 별개의 것은 아닙니다. 다시 말해, 이미
+{@link android.content.Context#startService startService()}로 시작된 서비스에 바인딩할 수도 있다는 뜻입니다. 예를
+들어, 배경 음악 서비스를 시작하려면 {@link android.content.Context#startService
+startService()}를 호출하되 재생할 음악을 식별하는 {@link android.content.Intent}를 사용하면 됩니다. 나중에,
+아마도 사용자가 플레이어에 좀 더 많은 통제권을 발휘하고자 하거나
+현재 노래에 대한 정보를 얻고자 할 때, 액티비티가 서비스에 바인딩될 수 있습니다. {@link
+android.content.Context#bindService bindService()}를 사용하면 됩니다. 이런 경우에는 {@link
+android.content.Context#stopService stopService()} 또는 {@link android.app.Service#stopSelf
+stopSelf()}도 클라이언트가 모두 바인딩 해제될 때까지 실제로 서비스를 중단시키지 않습니다. </p>
+
+
+<h3 id="LifecycleCallbacks">수명 주기 콜백 구현하기</h3>
+
+<p>액티비티와 마찬가지로 서비스에도 수명 주기 콜백 메서드가 있어 이를 구현하면 서비스의
+상태 변경 내용을 모니터링할 수 있고 적절한 시기에 작업을 수행할 수 있습니다. 다음의 골격
+서비스는 각 수명 주기 메서드를 설명한 것입니다.</p>
+
+<pre>
+public class ExampleService extends Service {
+ int mStartMode; // indicates how to behave if the service is killed
+ IBinder mBinder; // interface for clients that bind
+ boolean mAllowRebind; // indicates whether onRebind should be used
+
+ &#64;Override
+ public void {@link android.app.Service#onCreate onCreate}() {
+ // The service is being created
+ }
+ &#64;Override
+ public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
+ // The service is starting, due to a call to {@link android.content.Context#startService startService()}
+ return <em>mStartMode</em>;
+ }
+ &#64;Override
+ public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()}
+ return <em>mBinder</em>;
+ }
+ &#64;Override
+ public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
+ // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
+ return <em>mAllowRebind</em>;
+ }
+ &#64;Override
+ public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()},
+ // after onUnbind() has already been called
+ }
+ &#64;Override
+ public void {@link android.app.Service#onDestroy onDestroy}() {
+ // The service is no longer used and is being destroyed
+ }
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> 액티비티 수명 주기 콜백 메서드와는 달리 이와 같은 콜백 메서드를 구현하는 데에는
+슈퍼클래스 구현을 호출하지 <em>않아도</em> 됩니다.</p>
+
+<img src="{@docRoot}images/service_lifecycle.png" alt="" />
+<p class="img-caption"><strong>그림 2.</strong> 서비스 수명 주기입니다. 왼쪽의 다이어그램은
+서비스가 {@link android.content.Context#startService
+startService()}로 생성된 경우의 수명 주기를 나타내며 오른쪽의 다이어그램은 서비스가
+{@link android.content.Context#bindService bindService()}로 생성된 경우의 수명 주기를 나타낸 것입니다.</p>
+
+<p>이와 같은 메서드를 구현함으로써, 서비스 수명 주기의 두 가지 중첩된 루프를 모니터링할 수 있습니다. </p>
+
+<ul>
+<li>서비스의 <strong>수명 주기 전체</strong>는 {@link
+android.app.Service#onCreate onCreate()}가 호출된 시점과 {@link
+android.app.Service#onDestroy}가 반환된 시점 사이에 일어납니다. 액티비티와 마찬가지로 서비스는 자신의 초기 설정을
+{@link android.app.Service#onCreate onCreate()}에서 수행하며 남은 리소스를 모두 {@link
+android.app.Service#onDestroy onDestroy()}에 릴리스합니다. 예를 들어
+음악 재생 서비스의 경우 음악이 재생될 스레드를 {@link
+android.app.Service#onCreate onCreate()}로 생성하고, 그럼 다음 해당 스레드를 중단할 때에는 {@link
+android.app.Service#onDestroy onDestroy()}에서 할 수도 있습니다.
+
+<p>{@link android.app.Service#onCreate onCreate()}와 {@link android.app.Service#onDestroy
+onDestroy()} 메서드는 모든 서비스에 대해 호출됩니다. 이는 서비스가
+{@link android.content.Context#startService startService()}로 생성되었든 {@link
+android.content.Context#bindService bindService()}로 생성되었든 관계 없이 적용됩니다.</p></li>
+
+<li>서비스의 <strong>활성 수명 주기</strong>는 {@link
+android.app.Service#onStartCommand onStartCommand()} 또는 {@link android.app.Service#onBind onBind()}로의 호출과 함께 시작됩니다.
+각 메서드에 {@link
+android.content.Intent}가 전달되는데 이것은 각각 {@link android.content.Context#startService
+startService()} 또는 {@link android.content.Context#bindService bindService()} 중 하나에 전달된 것입니다.
+<p>서비스가 시작되면 수명 주기 전체가 종료되는 것과 동시에 활성 수명 주기도 종료됩니다
+(서비스는 {@link android.app.Service#onStartCommand
+onStartCommand()}가 반환된 뒤에도 여전히 활성 상태입니다). 서비스가 바인딩된 경우, 활성 수명 주기는 {@link
+android.app.Service#onUnbind onUnbind()}가 반환되면 종료됩니다.</p>
+</li>
+</ul>
+
+<p class="note"><strong>참고:</strong> 시작된 서비스를 중단하려면
+{@link android.app.Service#stopSelf stopSelf()} 또는 {@link
+android.content.Context#stopService stopService()}를 호출하면 되지만, 서비스에 대한 상응하는 콜백은
+없습니다(즉 {@code onStop()} 콜백이 없습니다). 그러므로, 서비스가 클라이언트에 바인딩되어 있지 않은 한
+시스템은 서비스가 중단되면 이를 소멸시킵니다. 수신되는 콜백은 {@link
+android.app.Service#onDestroy onDestroy()}가 유일합니다.</p>
+
+<p>그림 2는 서비스에 대한 일반적인 콜백 메서드를 나타낸 것입니다. 이 그림에서는
+{@link android.content.Context#startService startService()}로 생성된 서비스와
+{@link android.content.Context#bindService bindService()}로 생성된 서비스를
+구분하고 있지만, 어떤 식으로 시작되었든 모든 서비스는 클라이언트가 자신에 바인딩되도록 허용할 수 있다는 점을 명심하십시오.
+말하자면, {@link android.app.Service#onStartCommand
+onStartCommand()}로 처음 시작된 서비스(클라이언트가 {@link android.content.Context#startService startService()}를 호출해서)라고 해도
+여전히 {@link android.app.Service#onBind onBind()}로의 호출을 받을 수 있습니다(클라이언트가
+{@link android.content.Context#bindService bindService()}를 호출하는 경우).</p>
+
+<p>바인딩을 제공하는 서비스 생성에 대한 자세한 내용은 <a href="{@docRoot}guide/components/bound-services.html">바인딩된 서비스</a> 문서를 참조하십시오. 이 안에는 {@link android.app.Service#onRebind onRebind()}
+콜백 메서드에 대한 자세한 정보가 <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">바인딩된 서비스의
+수명 주기 관리</a>에 관한 섹션에
+담겨 있습니다.</p>
+
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>To learn how to query data from the system or other applications (such as contacts or media
+stored on the device), continue with the <b><a
+href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b>
+document.</p>
+-->
diff --git a/docs/html-intl/intl/ko/guide/components/tasks-and-back-stack.jd b/docs/html-intl/intl/ko/guide/components/tasks-and-back-stack.jd
new file mode 100644
index 000000000000..6b896f9d50ad
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/components/tasks-and-back-stack.jd
@@ -0,0 +1,578 @@
+page.title=작업 및 백 스택
+parent.title=액티비티
+parent.link=activities.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+<li><a href="#ActivityState">액티비티 상태 저장하기</a></li></li>
+<li><a href="#ManagingTasks">작업 관리하기</a>
+ <ol>
+ <li><a href="#TaskLaunchModes">시작 모드 정의하기</a></li>
+ <li><a href="#Affinities">유사성 처리하기</a></li>
+ <li><a href="#Clearing">백 스택 지우기</a></li>
+ <li><a href="#Starting">작업 시작하기</a></li>
+ </ol>
+</li>
+</ol>
+
+<h2>글</h2>
+<ol>
+ <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">
+Android식 멀티태스킹</a></li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+ <li><a href="{@docRoot}design/patterns/navigation.html">Android 디자인:
+탐색</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;} 매니페스트
+요소</a></li>
+ <li><a href="{@docRoot}guide/components/recents.html">개요 화면</a></li>
+</ol>
+</div>
+</div>
+
+
+<p>하나의 애플리케이션에는 보통 여러 개의 <a href="{@docRoot}guide/components/activities.html">액티비티</a>가 들어있습니다. 각 액티비티는
+사용자가 수행할 수 있는 특정한 종류의 작업을 중심으로 디자인되어야 하며 다른 액티비티를
+시작할 수 있는 기능이 있습니다. 예를 들어 이메일 애플리케이션에는 새 메시지 목록을 표시하는 하나의 액티비티가 있을 수 있습니다.
+사용자가 메시지를 하나 선택하면, 새 액티비티가 열려 해당 메시지를 볼 수 있게 합니다.</p>
+
+<p>액티비티는 기기에서 다른 애플리케이션에 존재하는 액티비티를 시작할 수도 있습니다. 예를 들어
+애플리케이션이 이메일 메시지를 보내고자 하는 경우, "전송" 작업을 수행할 인텐트를
+정의하여 이메일 주소와 메시지 등의 몇 가지 데이터를 포함시키면 됩니다. 그러면 다른 애플리케이션에서 가져온 액티비티 중
+이러한 종류의 인텐트를 처리한다고 스스로 선언한 것이 열립니다. 이 경우, 이 인텐트는
+이메일을 전송하기 위한 것이므로 이메일 애플리케이션의 "작성" 액티비티가 시작됩니다(같은 인텐트를
+지원하는 액티비티가 여러 개 있는 경우, 시스템은 사용자에게 어느 것을 사용할지 선택하도록 합니다). 이메일이 전송되면
+액티비티가 재개되고 해당 이메일 액티비티가 애플리케이션의 일부였던 것처럼 보입니다. 액티비티는
+서로 다른 애플리케이션에서 온 것일 수 있지만, Android는 두 액티비티를
+모두 같은 <em>작업</em> 안에 유지하여 이처럼 막힘 없는 사용자 환경을 유지합니다.</p>
+
+<p>작업이란 액티비티 컬렉션을 일컫는 말로, 사용자가 특정 작업을 수행할 때 이것과
+상호 작용합니다. 액티비티는 스택 안에 정렬되며(<em>백 스택</em>), 이때
+순서는 각 액티비티가 열린 순서와 같습니다.</p>
+
+<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h3>Adding fragments to a task's back stack</h3>
+
+<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example,
+suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the
+other being a layout to display an item from the list (fragment B). When the user selects an item
+from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be
+desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p>
+<p>In order to add fragment B to the back stack so that this is possible, you must call {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link
+android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment
+C.</p>
+<p>For more information about using fragments and adding them to the back stack, see the {@link
+android.app.Fragment} class documentation.</p>
+
+</div>
+</div>
+-->
+
+<p>기기 메인 스크린이 대다수 작업의 시작 지점입니다. 사용자가
+애플리케이션
+시작 관리자에 있는 아이콘(또는 메인 스크린의 바로 가기)을 터치하면 해당 애플리케이션의 작업이 전경으로 나옵니다. 해당 애플리케이션에 대한
+작업이 존재하지 않으면(이 애플리케이션을 최근에 사용한 적이 없는 경우), 새 작업이 생성되고
+해당 애플리케이션의 "기본" 액티비티가 스택에 있는 루트 액티비티로 열립니다.</p>
+
+<p>현재 액티비티가 또 다른 액티비티를 시작하는 경우, 새 액티비티가 스택의 맨 위로 밀어올려지고
+사용자의 초점이 이에 맞춰집니다. 이전 액티비티는 스택에 유지되지만, 중단됩니다. 액티비티가 중단되면
+시스템은 이 액티비티의 사용자 인터페이스의 현재 상태를 보존합니다. 사용자가
+<em>뒤로</em>
+ 버튼을 누르면, 현재 액티비티가 스택의 맨 위에서 튀어나오고(해당 액티비티는 소멸됩니다)
+이전 액티비티가 재개됩니다(이것의 UI 이전 상태가 복원됩니다). 스택에 있는 액티비티는
+결코 다시 정렬되지 않습니다. 다만 스택에서 밀어올려지거나 튀어나올 뿐입니다. 즉, 현재 액티비티에 의해
+시작되면 스택 위로 밀어올려지고, 사용자가 <em>뒤로</em> 버튼을 사용하여 액티비티를 떠나면 튀어나와 사라지는 것입니다. 따라서,
+백 스택은
+일종의 "후입선출" 객체 구조로서 작동한다고 할 수 있습니다. 그림 1은
+이 행동을 시간 표시 막대와 함께 표시하여 여러 액티비티 사이의 진행률을 보여주며,
+각 시점에서 현재 백 스택의 모습을 나타낸 것입니다.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 작업에 있는 각각의 새 액티비티가 백 스택에 항목을 추가하는
+방법을 나타낸 것입니다. 사용자가 <em>뒤로</em> 버튼을 누르면 현재
+액티비티가
+소멸되고 이전 액티비티가 재개됩니다.</p>
+
+
+<p>사용자가 계속해서 <em>뒤로</em> 버튼을 누르면, 스택에 있는 각 액티비티가 하나씩 튀어나가
+이전 것을
+드러내고, 마침내는 사용자가 메인 스크린으로 되돌아가게 됩니다(아니면 작업이 시작되었을 때
+실행 중이던 액티비티가 무엇이든 그것으로 되돌아갑니다). 스택에서 모든 액티비티가 제거되면 이 작업은 더 이상 존재하지 않게 됩니다.</p>
+
+<div class="figure" style="width:287px">
+<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p
+class="img-caption"><strong>그림 2.</strong> 두 개의 작업: 작업 B가 전경에서 사용자 상호 작용을 수신하는 한편,
+작업 A는 배경에서 재개되기를 기다립니다.</p>
+</div>
+<div class="figure" style="width:215px">
+ <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p
+class="img-caption"><strong>그림 3.</strong> 하나의 액티비티가 여러 번 인스턴트화됩니다.</p>
+</div>
+
+<p>작업이란 하나의 잘 짜여진 단위로 사용자가 새 작업을 시작할 때 "배경"으로 이동할 수도 있고
+<em>홈</em> 버튼을 통해 메인 스크린으로 이동할 수도 있습니다. 작업의 모든 액티비티는 배경에 있는 동안은
+중단되지만
+, 해당 작업에 대한 백 스택은 그대로 변함 없이 유지됩니다. 이 작업은 또 다른 작업이 발생하는 동안
+초점을 잃을 뿐입니다(그림 2 참조). 그런 다음 작업이 "전경"으로 되돌아와 사용자가
+이전에 하던 일을 계속할 수 있습니다. 예를 들어 현재 작업(작업 A)의 스택에 세 개의 액티비티가 있다고
+가정하면 그 중 둘은 현재 액티비티 아래에 있습니다. 사용자가 <em>홈</em>
+ 버튼을 누른 다음
+애플리케이션 시작 관리자로부터 새 애플리케이션을 시작합니다. 메인 스크린이 나타나면 작업 A는
+배경으로 이동합니다. 새 애플리케이션이 시작되면 시스템은 해당 애플리케이션에 대한 작업을 시작하며
+(작업 B) 여기에는 나름의 액티비티 스택이 딸려 있습니다. 해당 애플리케이션과
+상호 작용한 후, 사용자는 다시 홈으로 돌아와 원래 작업 A를 시작한
+애플리케이션을 선택합니다. 이제 작업 A가 전경으로 옵니다.
+이 스택에 있는 액티비티 세 개는 모두 멀쩡하고, 스택 맨 위에 있는 액티비티가
+재개됩니다. 이 시점에서
+사용자는 작업 B로 도로 전환할 수도 있습니다. 홈으로 이동하여 해당 작업을
+시작한 애플리케이션 아이콘을 선택하면 됩니다(아니면
+<a href="{@docRoot}guide/components/recents.html">개요 화면</a>에서 해당 앱의 작업을 선택해도 됩니다).
+이것이 Android에서 멀티태스킹을 하는 작업의 예시입니다.</p>
+
+<p class="note"><strong>참고:</strong> 여러 개의 작업을 배경에 한꺼번에 대기시킬 수 있습니다.
+하지만, 사용자가 수많은 배경 작업을 동시에 실행하면 시스템이 메모리를 복원하기 위해
+배경 액티비티를 소멸시키기 시작할 수 있고, 그러면 액티비티 상태가 손실됩니다.
+다음의 <a href="#ActivityState">액티비티 상태</a>에 관한 섹션을 참조하십시오.</p>
+
+<p>백 스택에 있는 액티비티는 결코 다시 정렬되지 않으므로, 애플리케이션에서
+사용자에게 하나 이상의 액티비티로부터 특정 액티비티를 시작하도록 허용하는 경우, 해당 액티비티의 새 인스턴스가
+생성되어 스택 위로 밀려옵니다(해당 액티비티의 기존 인스턴스를
+맨 위로 가져오는 대신). 따라서, 애플리케이션 안의 한 액티비티가 여러 번
+인스턴트화될 수 있으며(서로 다른 작업으로부터도 가능), 이를 나타낸 것이 그림 3입니다. 이 때문에 사용자가
+<em>뒤로</em> 버튼을 사용하여 뒤로 이동하는 경우, 액티비티의 각 인스턴스가 열린 순서대로 드러납니다
+(각자 나름의
+UI 상태를 가지고). 다만, 액티비티가 한 번 이상 인스턴트화되는 것을 원치 않으면 이 행동은 수정할 수
+있습니다. 그 방법에 대해서는 <a href="#ManagingTasks">작업 관리하기</a>에 관한 이후 섹션에서 이야기합니다.</p>
+
+
+<p>액티비티 및 작업에 대한 기본 행동을 요약하려면 다음과 같이 합니다.</p>
+
+<ul>
+ <li>액티비티 A가 액티비티 B를 시작하면 액티비티 A는 중단되지만, 시스템이 그 상태를
+(예: 스크롤 위치 및 양식에 입력된 텍스트 등) 보존합니다.
+사용자가 액티비티 B에 있는 동안 <em>뒤로</em> 버튼을 누르면 액티비티 A가 재개되며 상태도
+복원됩니다.</li>
+ <li>사용자가 <em>홈</em> 버튼을 눌러 작업을 떠나면 현재 액티비티가
+중단되고
+그 소속 작업이 배경으로 들어갑니다. 시스템은 작업에 속한 모든 액티비티의 상태를 보존합니다. 사용자가
+나중에 작업을 시작한 시작 관리자 아이콘을 선택하여 해당 작업을 재개하면, 그 작업이
+전경으로 나오고 스택 맨 위에서 액티비티를 재개합니다.</li>
+ <li>사용자가 <em>뒤로</em> 버튼을 누르면, 현재 액티비티가 스택에서 튀어나오고
+소멸됩니다.
+ 스택에 있던 이전 액티비티가 재개됩니다. 액티비티가 소멸되면, 시스템은 그 액티비티의 상태를
+보존하지 <em>않습니다.</em></li>
+ <li>액티비티는 여러 번 인스턴트화할 수 있으며, 다른 작업에서도 이를 수행할 수 있습니다.</li>
+</ul>
+
+
+<div class="note design">
+<p><strong>탐색 디자인</strong></p>
+ <p>Android에서 앱 탐색의 작동 원리를 자세히 알아보려면, Android 디자인의 <a href="{@docRoot}design/patterns/navigation.html">탐색</a> 가이드를 읽어보십시오.</p>
+</div>
+
+
+<h2 id="ActivityState">액티비티 상태 저장하기</h2>
+
+<p>위에서 논한 바와 같이, 시스템의 기본 행동은 액티비티가 중단되면 그 상태를 보존해두는
+것입니다. 이렇게 하면, 사용자가 이전 액티비티로 도로 이동했을 때 그에 속한 사용자 인터페이스가 이전 상태
+그대로 표시됩니다. 그러나 액티비티의 상태를 미리 보존할 수도 있으며 사전에 이렇게 <strong>해야 합니다.</strong>
+이때에는, 액티비티가 소멸되고 다시 만들어야 하는 경우를 대비해
+콜백 메서드를 사용합니다.</p>
+
+<p>시스템이 액티비티 중 하나를 중단시키는 경우(예를 들어 새 액티비티가 시작되었을 때 또는 작업이
+배경으로 이동하는 경우), 시스템은 시스템 메모리를 회복해야 하는 경우 액티비티를
+완전히 소멸시켜버릴 수도 있습니다. 이런 상황이 벌어지면, 액티비티 상태에 대한 정보는 손실됩니다. 이런 일이 벌어지더라도,
+시스템은 여전히
+백 스택에 해당 액티비티의 자리가 있다는 것을 알고 있습니다. 다만 액티비티가 스택 맨 위로 올라오면
+시스템이 이를 (재개하는 것이 아니라) 재생성해야만 합니다. 사용자의 작업 내용을
+잃어버리는 불상사를 피하려면 그 내용을 미리 보존해두어야 합니다. 이때 액티비티의
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} 콜백
+메서드를 구현하는 방법을 씁니다.</p>
+
+<p>액티비티 상태를 저장하는 방법에 대한 자세한 정보는 <a href="{@docRoot}guide/components/activities.html#SavingActivityState">액티비티</a>
+문서를 참조하십시오.</p>
+
+
+
+<h2 id="ManagingTasks">작업 관리하기</h2>
+
+<p>Android가 작업과 백 스택을 관리하는 방식은 위에 설명된 바와 같고&mdash;같은 작업 안에서
+연이어 시작된 모든 작업을 한곳에 배치하되 "후입선출" 스택에 두는 것&mdash;이 방식은
+대부분의 애플리케이션에 아주 효과적입니다. 여러분은 액티비티가 작업과 연관된 방식이나
+백 스택에서의 존재 방식에 대해 염려하지 않아도 됩니다. 그러나, 정상적인 동작을 인터럽트하기로 결정할 수도
+있습니다. 애플리케이션의 액티비티 하나가 시작되면 새 작업을 시작하려
+할 수도 있습니다(현재 작업 내에 배치되는 것 대신에). 아니면, 액티비티를 시작하면 그것의
+기존 인스턴스 하나를 앞으로 가져오고자 할 수도 있습니다(백 스택 맨 위에서 새 인스턴스를
+생성하는 것 대신에). 또는 백 스택에서 사용자가 작업을 떠날 때의 루트 액티비티를 제외하고
+모든 액티비티를 지우고자 할 수도 있습니다.</p>
+
+<p>이 모든 것과 그 외에도 많은 것을 할 수 있는 것이 바로
+<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+매니페스트 요소 안에 있는 속성과,
+{@link android.app.Activity#startActivity startActivity()}에 전달한 인텐트에 있는 플래그입니다.</p>
+
+<p>이런 면에서, 여러분이 사용할 수 있는 주요 <a href="{@docRoot}guide/topics/manifest/activity-element.html">
+{@code &lt;activity&gt;}</a> 속성은 다음과 같습니다.</p>
+
+<ul class="nolist">
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">
+ {@code taskAffinity}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">
+ {@code launchMode}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
+ {@code allowTaskReparenting}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">
+ {@code clearTaskOnLaunch}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
+ {@code alwaysRetainTaskState}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">
+ {@code finishOnTaskLaunch}</a></li>
+</ul>
+
+<p>그리고 다음은 여러분이 사용할 수 있는 주요 인텐트 플래그입니다.</p>
+
+<ul class="nolist">
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li>
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li>
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li>
+</ul>
+
+<p>다음 섹션에서는 이와 같은 매니페스트 속성과 인텐트 플래그를 사용하여
+액티비티가 작업과 연관되는 방식을 정의하고 백 스택에서 액티비티가 동작하는 방식을 정의하는 방법을 배우게 됩니다.</p>
+
+<p>이외에도 별도로 작업과 액티비티를 표시하는 방법에 대한 고려 사항과
+개요 화면에서의 관리 방법을 논합니다. 자세한 정보는 <a href="{@docRoot}guide/components/recents.html">개요 화면</a>을
+참조하십시오. 보통은 개요 화면에 작업과 액티비티가 어떻게 표현될지는
+시스템이 정의하도록 두어야 합니다. 이 동작을 개발자가 수정할 필요도 없습니다.</p>
+
+<p class="caution"><strong>주의:</strong> 대부분의 애플리케이션은 액티비티와 작업에 대한
+기본 동작을 인터럽트하지 않는 것이 정상입니다. 액티비티가 기본 동작을 수정하는 것이 필요하다는
+판단이 서면, 시작 과정 중에 액티비티의 유용성을 테스트하십시오.
+또한 다른 액티비티와 작업에서 <em>뒤로</em> 버튼을 써서 해당 액티비티로 돌아올 때에도 유용성을 테스트해야 합니다.
+사용자의 예상되는 동작과 충돌할 가능성이 있는 탐색 동작을 꼭 테스트하십시오.</p>
+
+
+<h3 id="TaskLaunchModes">시작 모드 정의하기</h3>
+
+<p>시작 모드를 사용하면 액티비티의 새 인스턴스가 현재 작업과 연관된 방식을 정의할 수 있게
+해줍니다. 여러 가지 시작 모드를 두 가지 방식으로 정의할 수 있습니다.</p>
+<ul class="nolist">
+ <li><a href="#ManifestForTasks">매니페스트 파일 사용하기</a>
+ <p>매니페스트 파일에서 액티비티를 선언하는 경우, 액티비티가 시작될 때 여러 작업과 어떤 식으로
+연관을 맺어야 하는지 지정할 수 있습니다.</li>
+ <li><a href="#IntentFlagsForTasks">인텐트 플래그 사용하기</a>
+ <p>{@link android.app.Activity#startActivity startActivity()}를 호출하는 경우
+{@link android.content.Intent}에 플래그를 포함시켜 새 액티비티가 현재 작업과 어떻게 연관되어야 할지(또는
+애초에 연관을 맺을지 아닐지) 선언하도록 할 수 있습니다.</p></li>
+</ul>
+
+<p>따라서, 액티비티 A가 액티비티 B를 시작하면 액티비티 B는 자신의 매니페스트에서
+현재 작업과 연관을 맺는 데 적당한 방식(연관을 맺어야 한다면)을 정의할 수 있고 액티비티 A 또한
+액티비티 B가 현재 작업과 연관을 맺는 방식을 요청할 수 있습니다. 두 액티비티가 모두 액티비티 B가 작업과
+연관되는 방식을 정의하는 경우, 액티비티 A의 요청(인텐트에 정의된 바를 따름)을 액티비티 B의
+요청(자신의 매니페스트에서 정의)보다 우위로 인식합니다.</p>
+
+<p class="note"><strong>참고:</strong> 매니페스트 파일에 사용할 수 있는 시작 모드 중에는
+인텐트의 플래그로 사용할 수는 없는 것도 있으며, 이와 마찬 가지로 인텐트의 플래그로 사용할 수 있는 시작 모드 중에는
+매니페스트에서 정의할 수 없는 것도 있습니다.</p>
+
+
+<h4 id="ManifestForTasks">매니페스트 파일 사용하기</h4>
+
+<p>매니페스트 파일에서 액티비티를 선언하는 경우, 액티비티가 작업과
+어떤 식으로 연관되어야 할지 지정하려면 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+요소의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a> 속성을 사용하면 됩니다.</p>
+
+<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a> 속성은 액티비티가 작업 안으로 들어가며 시작되는 방법에 대한 지침을
+나타냅니다.
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>
+속성에 할당할 수 있는 시작 모드는 네 가지가 있습니다.</p>
+
+<dl>
+<dt>{@code "standard"} (기본 모드)</dt>
+ <dd>기본입니다. 시스템이 액티비티가 시작된 작업에서 액티비티의 새 인스턴스를 만들고
+인텐트의 경로를 이것으로 지정합니다. 액티비티는 여러 번 인스턴트화될 수 있고,
+각 인스턴스는 서로 다른 작업에 속할 수 있으며 한 작업에 여러 개의 인스턴스가 있을 수 있습니다.</dd>
+<dt>{@code "singleTop"}</dt>
+ <dd>액티비티의 인스턴스가 이미 현재 작업의 맨 위에 존재하는 경우, 시스템은 인텐트의 경로를
+해당 인스턴스로 지정합니다. 이때 액티비티의 새 인스턴스를 만들기보다는 해당 인스턴스의 {@link
+android.app.Activity#onNewIntent onNewIntent()} 메서드를 호출하는 방법을
+통합니다. 액티비티는 여러 번 인스턴트화될 수 있고, 각 인스턴스는 서로 다른 작업에
+속할 수 있으며 한 작업에 여러 개의 인스턴스가 있을 수 있습니다(다만 백 스택의 맨 위에 있는
+액티비티가 액티비티의 기존 인스턴스가 <em>아닌</em> 경우에만 이것이 적용됩니다).
+ <p>예를 들어 어느 작업의 백 스택이 루트 액티비티 A와 액티비티 B, C, 그리고 맨 위의 액티비티 D로
+구성되어 있다고 가정합니다(이 스택은 A-B-C-D 형태를 띠며 D가 맨 위에 있습니다). 유형 D의 액티비티에 대한 인텐트가 도착합니다.
+D에 기본 {@code "standard"} 시작 모드가 있는 경우, 클래스의 새 인스턴스가 시작되고 이 스택은
+A-B-C-D-D가 됩니다. 하지만, D의 시작 모드가 {@code "singleTop"}인 경우, D의
+기존 인스턴스가 해당 인텐트를 {@link
+android.app.Activity#onNewIntent onNewIntent()}를 통해 받게 됩니다. 이것이 스택의 맨 위에 있기 때문입니다. 스택은
+계속 A-B-C-D로 유지됩니다. 그러나 유형 B의 액티비티에 대한 인텐트가 도착하는 경우,
+B의 새 인스턴스가 스택에 추가되며 이는 액티비티의 시작 모드가 {@code "singleTop"}이더라도 무관하게 적용됩니다.</p>
+ <p class="note"><strong>참고:</strong> 어느 액티비티의 새 인스턴스가 생성되면,
+사용자가 <em>뒤로</em> 버튼을 눌러 이전 액티비티로 되돌아갈 수 있게 됩니다. 그러나 액티비티의 기존
+인스턴스가
+새 인텐트를 처리하는 경우, 사용자가 <em>뒤로</em> 버튼을 눌러도 새 인텐트가 {@link android.app.Activity#onNewIntent
+onNewIntent()}에 도착하기 전의 액티비티
+상태로
+되돌아갈 수 없습니다.</p>
+</dd>
+
+<dt>{@code "singleTask"}</dt>
+ <dd>시스템이 새 작업을 만들고 새 작업의 루트에 있는 액티비티를 인스턴트화합니다.
+하지만, 액티비티의 인스턴스가 이미 별개의 작업에 존재하는 경우, 시스템은 인텐트의 경로를
+기존 인스턴스로 지정합니다. 이때 새 인스턴스를 만들기보다 해당 인스턴스의 {@link
+android.app.Activity#onNewIntent onNewIntent()} 메서드를 호출하는 방법을 통합니다. 한 번에
+액티비티 인스턴스 한 개씩만 존재할 수 있습니다.
+ <p class="note"><strong>참고:</strong> 액티비티가 새 작업에서 시작되더라도,
+<em>뒤로</em> 버튼을 누르면 여전히 사용자를 이전 액티비티로 돌려보냅니다.</p></dd>
+<dt>{@code "singleInstance"}.</dt>
+ <dd>{@code "singleTask"}와 같습니다. 다만 시스템이 인스턴스를 보유하고 있는 작업 안으로
+다른 어떤 액티비티도 시작하지 않는다는 것은 예외입니다. 액티비티는 언제나 자신의 작업의 유일무이한 구성원입니다.
+이것으로 시작한 액티비티는 모두 별개의 작업에서 열립니다.</dd>
+</dl>
+
+
+<p>또 다른 예로 Android 브라우저 애플리케이션이 있습니다. 이것은 웹 브라우저 액티비티가 항상
+자신만의 작업에서 열려야 한다고 선언합니다. 이때 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> 요소에 {@code singleTask} 시작 모드를 지정하는 방법을 씁니다.
+다시 말해 애플리케이션이 Android 브라우저를 열라는 인텐트를 발행하면
+브라우저의 액티비티가 애플리케이션과 같은 작업에 배치되지 <em>않는다</em>는
+뜻입니다. 그 대신, 브라우저에 대한 새 작업이 시작되거나, 브라우저에 이미
+배경에서 실행 중인 작업이 있는 경우 해당 작업이 전경으로 불려나와 새 인텐트를 처리하게
+됩니다.</p>
+
+<p>액티비티가 새 작업에서 시작되었든 액티비티를 시작한 것과 같은 작업에서 시작되었든 관계 없이
+<em>뒤로</em> 버튼을 사용하면 언제나 사용자를 이전 액티비티로 돌려보냅니다. 다만,
+{@code singleTask} 시작 모드를 나타내는 액티비티를 시작한 다음 해당
+액티비티의 인스턴스가 이미 배경 작업에 존재하는 경우, 그 작업 전체가 전경에 불려나옵니다. 이 시점에서
+백 스택에는 이제 앞으로 가져온 작업에서 가져온 모든 액티비티가 포함되어 있으며, 이는 스택의
+맨 위에 위치합니다. 그림 4는 이와 같은 유형의 시나리오를 나타낸 것입니다.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" />
+<p class="img-caption"><strong>그림 4.</strong> 시작 모드가 "singleTask"인 액티비티가
+백 스택에 추가되는 방법을 표현한 것입니다. 이 액티비티가 이미 자신의 백 스택을 가지고 있는
+배경 작업의 일부인 경우, 해당 백 스택도 모두 전경으로
+불려나오며, 이는 현재 작업 위에 배치됩니다.</p>
+
+<p>매니페스트 파일에서 시작 모드를 사용하는 것에 대한 자세한 정보는
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+요소 문서를 참조하십시오. 여기에서 {@code launchMode} 속성과 허용된 값을 더 자세히
+논합니다.</p>
+
+<p class="note"><strong>참고:</strong> 액티비티에 대하여 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 속성으로 지정한 동작을
+재정의하려면 액티비티를 시작한 인텐트에 포함된 플래그를 사용하면 됩니다. 이 내용은
+다음 섹션에서 논합니다.</p>
+
+
+
+<h4 id="#IntentFlagsForTasks">인텐트 플래그 사용하기</h4>
+
+<p>액티비티를 시작할 때면, 액티비티가 자신의 작업과 연관되는 기본 방식을 수정할 수 있습니다.
+{@link
+android.app.Activity#startActivity startActivity()}에 전달한 인텐트 안에 있는 플래그를 포함시키면 됩니다. 기본 동작을 수정하는 데 사용할 수 있는
+플래그는 다음과 같습니다.</p>
+
+<p>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt>
+ <dd>액티비티를 새 작업에서 시작합니다. 지금 시작하고 있는 액티비티에 대해 이미 실행 중인 작업이 있으면,
+해당 작업의 마지막 상태를 복원하여 전경으로 불려나오고 액티비티는 새 인텐트를
+{@link android.app.Activity#onNewIntent onNewIntent()}에서 수신합니다.
+ <p>이렇게 하면 {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 값에서와 같은 동작을 발생시키며,
+이는 이전 섹션에서 논한 것과 같습니다.</p></dd>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt>
+ <dd>시작되고 있는 액티비티가 현재 액티비티인 경우(백 스택 맨 위에 있는), 해당 액티비티의 새 인스턴스를 생성하는 대신 기존
+인스턴스가 {@link android.app.Activity#onNewIntent onNewIntent()}에
+대한 호출을 받습니다.
+ <p>이렇게 하면 {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> 값에서와 같은 동작을 발생시키며,
+이는 이전 섹션에서 논한 것과 같습니다.</p></dd>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt>
+ <dd>시작되고 있는 액티비티가 이미 현재 작업에서 실행 중인 경우, 해당 액티비티의
+새 인스턴스를 시작하는 대신 그 위에 있는 모든 다른 액티비티가
+소멸되고 이 인텐트는 해당 액티비티(이제 맨 위로 올라옴)의 재개된 인스턴스로,
+{@link android.app.Activity#onNewIntent onNewIntent()}를 통해 전달됩니다.
+ <p>이 동작을 발생시키는 <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>
+속성에 대한 값은 없습니다.</p>
+ <p>{@code FLAG_ACTIVITY_CLEAR_TOP}는
+{@code FLAG_ACTIVITY_NEW_TASK}와 함께 쓰이는 경우가 가장 보편적입니다.
+이들 플래그를 함께 사용하면 다른 작업에 있는 기존 액티비티의 위치를
+찾아 이를 인텐트에 응답할 수 있는 위치에 놓을 한 가지 방편이 됩니다. </p>
+ <p class="note"><strong>참고:</strong> 지정된 액티비티의 시작 모드가
+{@code "standard"}인 경우,
+이것 또한 스택에서 제거되고 그 자리에 새 인스턴스가 대신 생성되어 수신되는 인텐트를
+처리하게 됩니다. 이는 시작 모드가
+{@code "standard"}인 경우, 새 인텐트에 대해서는 항상 새 인스턴스가 생성되기 때문입니다. </p>
+</dd>
+</dl>
+
+
+
+
+
+<h3 id="Affinities">유사성 처리하기</h3>
+
+<p><em>유사성</em>이란 액티비티가 어느 작업에 소속되기를 선호하는지를 나타내는 것입니다. 기본적으로,
+같은 애플리케이션에서 나온 액티비티는 서로 유사성을 지니고 있습니다. 따라서, 기본적으로
+같은 애플리케이션 안에 있는 모든 액티비티는 같은 작업 안에 있는 것을 선호합니다. 하지만 액티비티에 대한 기본 유사성은 개발자가
+수정할 수 있습니다. 각기 다른 애플리케이션에서 정의된
+액티비티가 하나의 유사성을 공유할 수도 있고, 같은 애플리케이션에서 정의된 여러 액티비티에
+서로 다른 작업 유사성을 할당할 수도 있습니다.</p>
+
+<p>어느 액티비티라도 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+요소의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> 속성을
+사용하여 유사성을 수정할 수 있습니다.</p>
+
+<p><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+속성은 문자열 값을 취합니다. 이는
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">
+{@code &lt;manifest&gt;}
+</a> 요소에서 선언한 기본 패키지 이름과 달리 고유해야 합니다. 왜냐하면 시스템이 이 이름을 사용하여 애플리케이션의 기본 작업 유사성을
+식별하기 때문입니다.</p>
+
+<p>유사성이 역할을 갖는 것은 다음과 같은 두 가지 상황에서입니다.</p>
+<ul>
+ <li>액티비티를 시작한 인텐트에
+{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
+ 플래그가 들어 있는 경우.
+
+<p>새로운 액티비티는 기본적으로
+{@link android.app.Activity#startActivity startActivity()}를 호출한 액티비티의 작업 안으로 들어가며 시작됩니다. 이것은 발신자와 같은
+백 스택 위로 밀어내집니다. 하지만
+{@link android.app.Activity#startActivity startActivity()}에
+전달된 인텐트에 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
+ 플래그가 들어있는 경우, 시스템은 새 액티비티를 담을 다른 작업을 찾습니다. 이는 새 작업인 경우가 많습니다.
+그렇지만 꼭 그래야 하는 것은 아닙니다. 새 액티비티와 같은 유사성을 가진 기존 작업이 이미 존재하는 경우,
+해당 액티비티는 그 작업 안으로 들어가며 시작됩니다. 그렇지 않으면, 새 작업을 시작합니다.</p>
+
+<p>이 플래그 때문에 액티비티가 새 작업을 시작하게 되고 사용자가 <em>홈</em> 버튼을 눌러 이 액티비티를
+떠나고자
+하는 경우, 사용자가 작업으로 도로 이동할 방법이 있어야 합니다. 엔티티 중에는(예를 들어
+알림 관리자) 액티비티를 항상 외부 작업으로만 시작하고 자신의 일부로서는 절대 시작하지 않는 것이 있습니다.
+따라서 이들은 {@code FLAG_ACTIVITY_NEW_TASK}를
+{@link android.app.Activity#startActivity startActivity()}에 전달하는 인텐트에 포함시킵니다.
+이 플래그를 사용할 수 있는 외부 엔티티가
+호출할 수 있는 액티비티를 가지고 있는 경우, 사용자가 시작된 작업에 돌아갈 수 있는
+방법을 따로 가지고 있어야 합니다. 예를 들어 시작 관리자 아이콘을 이용한다든지 하는 방법입니다(작업의 루트 액티비티에
+{@link android.content.Intent#CATEGORY_LAUNCHER} 인텐트 필터가 있습니다. 아래의 <a href="#Starting">작업 시작하기</a> 섹션을 참조하십시오).</p>
+</li>
+
+ <li>액티비티의 <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
+{@code allowTaskReparenting}</a> 속성이 {@code "true"}로 설정된 경우.
+ <p>이 경우, 액티비티는 자신이 시작한 작업에서 벗어나 유사성을 가진 다른 작업이 전경으로
+나오면 그 작업으로 이동할 수 있습니다.</p>
+ <p>예를 들어 선택한 몇몇 도시에서 기상 상태를 예보하는 어느 액티비티가
+여행 애플리케이션의 일부로 정의되어 있다고 가정합니다. 이것은 같은 애플리케이션에 있는
+다른 여러 액티비티와 같은 유사성을 가지며(기본 애플리케이션 유사성) 이 속성으로 상위 재지정을 허용하기도 합니다.
+액티비티 중 하나가 일기 예보 액티비티를 시작하면, 이는 처음에는 액티비티와 같은 작업에
+속합니다. 하지만 여행 애플리케이션의 작업이 전경으로 불려나오면
+일기 예보 액티비티는 그 작업에 다시 할당되며 그 안에 표시됩니다.</p>
+</li>
+</ul>
+
+<p class="note"><strong>팁:</strong> {@code .apk} 파일에 사용자 쪽에서 보기에 하나 이상의 "애플리케이션"이
+들어있는 경우, <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+속성을 사용하여 각 "애플리케이션"과 연관된 액티비티에 서로 다른 유사성을 할당하는 것이 좋습니다.</p>
+
+
+
+<h3 id="Clearing">백 스택 지우기</h3>
+
+<p>사용자가 작업을 오랜 시간 동안 떠나 있으면, 시스템이 루트 액티비티만 빼고 모든 액티비티를
+해당 작업에서 지웁니다. 사용자가 다시 작업으로 돌아오면, 루트 액티비티만 복원됩니다.
+시스템이 이런 식으로 동작하는 것은 오랜 시간이 지난 다음에는 사용자가 전에 하던 일을 중단하고
+새로운 일을 시작하기 위해 작업에 돌아올 가능성이 크기 때문입니다. </p>
+
+<p>이 동작을 수정하는 데 사용할 수 있는 액티비티 속성이 몇 가지 있습니다. </p>
+
+<dl>
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
+</dt>
+<dd>이 속성이 작업의 루트 액티비티 안에서 {@code "true"}로 설정되어 있는 경우,
+방금 설명한 기본 동작이 일어나지 않습니다.
+작업은 오랜 시간이 지난 뒤에도 자신의 스택에 있는 모든 액티비티를 유지합니다.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt>
+<dd>이 속성이 작업의 루트 액티비티 안에서 {@code "true"}로 설정되어 있는 경우,
+사용자가 작업을 떠났다가 다시 돌아올 때마다 스택을 루트 액티비티까지
+지웁니다. 바꿔 말하면, 이것은
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
+{@code alwaysRetainTaskState}</a>와 정반대입니다. 사용자는 항상 작업의 초기 상태로 돌아오게 되며,
+이는 아주 잠깐 동안만 작업을 떠난 경우에도 마찬가지입니다.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
+</dt>
+<dd>이 속성은 <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>와 같지만,
+작업 전체가 아니라
+하나의 액티비티에서 작동합니다. 이것은 루트 액티비티를 포함한 모든 액티비티가 없어지게
+하기도 합니다. 이것을 {@code "true"}로 설정하면,
+액티비티는 현재 세션에 대해서만 작업의 일부로 유지됩니다. 사용자가 작업을 떠났다가
+다시 돌아오면 이 작업은 더 이상 존재하지 않습니다.</dd>
+</dl>
+
+
+
+
+<h3 id="Starting">작업 시작하기</h3>
+
+<p>액티비티를 작업의 진입 지점으로 설정하려면 여기에 작업에서 지정한 대로
+{@code "android.intent.action.MAIN"}이 있는 인텐트 필터를 부여하고
+{@code "android.intent.category.LAUNCHER"}를
+지정된 카테고리로 설정하면 됩니다. 예:</p>
+
+<pre>
+&lt;activity ... &gt;
+ &lt;intent-filter ... &gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+ ...
+&lt;/activity&gt;
+</pre>
+
+<p>이런 종류의 인텐트 필터를 사용하면 액티비티에 대한 아이콘과 레이블이
+애플리케이션 시작 관리자에 표시되어 사용자에게 액티비티를 시작할 방법을 부여하며,
+액티비티를 시작하고 나면 이것이 생성한 작업에 언제든 돌아올 수 있게 됩니다.
+</p>
+
+<p>이 두 번째 능력이 중요합니다. 사용자는 작업을 떠났다가 이 액티비티 시작 관리자를 사용하여 나중에 작업에
+돌아올 수 있어야 합니다. 이러한 이유로, 액티비티가 항상 작업을 시작하는 것으로 표시하는 <a href="#LaunchModes">시작
+모드</a> 두 가지, 즉 {@code "singleTask"}와
+{@code "singleInstance"}는 액티비티에
+{@link android.content.Intent#ACTION_MAIN}
+ 및 {@link android.content.Intent#CATEGORY_LAUNCHER} 필터가 있을 때에만 사용해야 합니다. 예를 들어 필터가 누락되면 다음과 같은 일이
+발생합니다. 어느 인텐트가 {@code "singleTask"} 액티비티를 시작하여 새 작업을 시작하고,
+사용자가 이 작업에서 일하며 어느 정도 시간을 보냅니다. 그런 다음 사용자가 <em>홈</em>
+ 버튼을 누릅니다. 이제 이 작업은 배경으로 전송되었으며 눈에 보이지 않습니다. 이제 사용자가 작업으로 되돌아갈
+방법이 없어졌습니다. 이는 애플리케이션 시작 관리자에 표시되지 않기 때문입니다.</p>
+
+<p>사용자가 액티비티로 되돌아갈 수 있도록 하는 것을 원치 않는 경우,
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 요소의
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a>
+를 {@code "true"}로 설정하면 됩니다(<a href="#Clearing">스택 지우기</a>를 참조하십시오).</p>
+
+<p>작업과 액티비티가 개요 화면에서 어떻게 표시되고 관리되는지에 대한
+자세한 정보는 <a href="{@docRoot}guide/components/recents.html">
+개요 화면</a>에서 확인하실 수 있습니다.</p>
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For more information about how to use intents to
+activate other application components and publish the intents to which your components
+respond, continue with the <b><a
+href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
+Filters</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/ko/guide/index.jd b/docs/html-intl/intl/ko/guide/index.jd
new file mode 100644
index 000000000000..73af3df9b8c0
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/index.jd
@@ -0,0 +1,74 @@
+page.title=Android 소개
+
+@jd:body
+
+
+<div class="sidebox" style="width:220px"><!-- width to match col-4 below -->
+<p>앱의 작동 원리를 배워보고자 한다면, 우선
+<a href="{@docRoot}guide/components/fundamentals.html">앱 기본 항목</a>부터 시작하십시오.</p>
+<p>바로 코딩을 시작하려면, <a href="{@docRoot}training/basics/firstapp/index.html">첫 앱 구축하기</a>를 읽어보십시오.</p>
+</div>
+
+<p>Android는 풍성한 애플리케이션 프레임워크를 제공하여 Java 언어 환경에서 실행되는
+모바일 기기에서 사용할 혁신적인 앱과 게임을 구축할 수 있습니다. 왼쪽 탐색 영역에 목록으로 나열된
+여러 문서에서 Android의 다양한 API를 사용하여 앱을 구축하는 방법에 대한 상세한 정보를 제공합니다.</p>
+
+<p>Android 개발을 처음 시도하신다면, 다음과 같은
+Android 앱 프레임워크 기본 개념을 숙지하는 것이 중요합니다.</p>
+
+
+<div class="landing-banner">
+
+<div class="col-6">
+
+<h4>앱은 여러 개의 진입 지점을 제공합니다.</h4>
+
+<p>Android 앱은 여러 가지 고유한 구성 요소들의 조합으로 구축되며, 이러한 구성 요소는 개별적으로
+호출할 수도 있습니다. 예를 들어 어떤 하나의 <em>액티비티</em>가 사용자 인터페이스를 위한
+화면을 하나 제공하고, <em>서비스</em>가 배경에서 독립적으로 작업을 수행할
+수 있습니다.</p>
+
+<p>한 구성 요소에서 또 다른 구성 요소를 시작하려면 <em>인텐트</em>를 사용하면 됩니다. 심지어 다른 앱에서도
+구성 요소를 시작할 수 있습니다. 지도 앱에서 주소를 표시하는 액티비티를 시작하는 것이 좋은 예입니다. 이 모델은
+하나의 앱에 대한 여러 개의 진입 지점을 제공하여 어느 앱이라도 다른 여러 앱이 호출할 수 있는 작업에 대해
+사용자의 "기본" 앱 역할을 합니다.</p>
+
+
+<p><b>자세히 알아보기:</b></p>
+<ul class="nolist">
+<li><a href="{@docRoot}guide/components/fundamentals.html">앱 기본 항목</a>
+<li><a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a>
+<li><a href="{@docRoot}guide/components/activities.html">액티비티</a>
+</ul>
+
+</div>
+
+
+<div class="col-6">
+
+<h4>앱은 여러 가지 기기에 맞게 변경됩니다.</h4>
+
+<p>Android는 적응형 앱 프레임워크를 제공하여 여러 가지 기기 구성에 맞게
+고유한 리소스를 제공할 수 있습니다. 예를 들어, 여러 가지 화면 크기에 맞춰 각기 다른 XML
+레이아웃 파일을 생성하면 시스템이 현재 기기의 화면 크기를 근거로
+어느 레이아웃을 적용할지 결정합니다.</p>
+
+<p>앱 기능이 특정한 하드웨어(예: 카메라)를 필요로 하는 경우 런타임에
+기기 특징의 기능을 쿼리할 수 있습니다. 필요하다면 앱이 필요로 하는 기능을 선언할 수도 있습니다.
+그러면 Google Play Store와 같은 앱 마켓에서 해당 기능을 지원하지 않는 기기에서
+설치를 허용하지 않습니다.</p>
+
+
+<p><b>자세히 알아보기:</b></p>
+<ul class="nolist">
+<li><a href="{@docRoot}guide/practices/compatibility.html">기기 호환성</a>
+<li><a href="{@docRoot}guide/topics/resources/overview.html">리소스 개요</a>
+<li><a href="{@docRoot}guide/topics/ui/overview.html">사용자 인터페이스 개요</a>
+</ul>
+
+</div>
+
+</div><!-- end landing-banner -->
+
+
+
diff --git a/docs/html-intl/intl/ko/guide/topics/manifest/manifest-intro.jd b/docs/html-intl/intl/ko/guide/topics/manifest/manifest-intro.jd
new file mode 100644
index 000000000000..c3550d0e7dc8
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/manifest/manifest-intro.jd
@@ -0,0 +1,517 @@
+page.title=앱 매니페스트
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+<li><a href="#filestruct">매니페스트 파일의 구조</a></li>
+<li><a href="#filec">파일 규칙</a>
+<li><a href="#filef">파일 기능</a>
+ <ol>
+ <li><a href="#ifs">인텐트 필터</a></li>
+ <li><a href="#iconlabel">아이콘 및 레이블</a></li>
+ <li><a href="#perms">권한</a></li>
+ <li><a href="#libs">라이브러리</a></li>
+ </ol></li>
+</ol>
+</div>
+</div>
+
+<p>
+ 모든 애플리케이션에는 루트 라이브러리에 AndroidManifest.xml 파일(정확히
+이 이름으로)이 있어야 합니다. <span itemprop="description">매니페스트 파일은
+Android 시스템에 대한 여러분의 앱 관련 필수 정보를 나타냅니다.
+즉 앱의 코드를 실행하기 전에 시스템이 반드시 필요로 하는 정보를
+말합니다.</span> 매니페스트가 하는 일에는 여러 가지가 있지만, 그 중에서 몇 가지만 소개하면 다음과 같습니다.
+</p>
+
+<ul>
+<li>애플리케이션에 대한 Java 패키지의 이름을 나타냅니다.
+패키지 이름이 애플리케이션에 대한 고유한 식별자 역할을 합니다.</li>
+
+<li>애플리케이션의 구성 요소를 설명합니다. 액티비티,
+서비스, 브로드캐스트 수신기 및 콘텐츠 제공자 등 애플리케이션을 이루는 여러 항목을
+말합니다. 이것은 각 구성 요소를 구현하는 클래스의 이름을 나타내고
+각각의 기능을 게시합니다(예를 들어 처리할 수 있는 {@link android.content.Intent
+Intent} 메시지 종류 등). 이러한 선언을 통해 Android 시스템이 여러 구성 요소가
+각각 무엇인지 알게 되고, 어떤 조건에서 시작해야 하는지 알 수 있습니다.</li>
+
+<li>어느 프로세스가 애플리케이션 구성 요소를 호스팅할 것인지 결정합니다.</li>
+
+<li>API의 보호된 부분에 액세스하여 다른 애플리케이션과 상호 작용하려면
+애플리케이션에 어느 권한이 꼭 필요한지 선언합니다.</li>
+
+<li>또한, 이 애플리케이션의 구성 요소와 상호 작용하려면 다른 애플리케이션이
+반드시 가지고 있어야 하는 권한도 선언합니다.</li>
+
+<li>이는 애플리케이션이 실행 중일 때 프로파일링과 기타 정보를 제공하는
+{@link android.app.Instrumentation} 클래스를 목록으로 표시합니다. 이러한 선언이 매니페스트에 나타나는 것은
+애플리케이션이 개발 중이고 테스트되는 단계에만 국한됩니다.
+이들은 애플리케이션이 게시되기 전에 제거됩니다.</li>
+
+<li>이는 애플리케이션이 필요로 하는 Android API의 최소 레벨을
+선언합니다.</li>
+
+<li>애플리케이션이 연결되어야 하는 라이브러리를 목록으로 표시합니다.</li>
+</ul>
+
+
+<h2 id="filestruct">매니페스트 파일의 구조</h2>
+
+<p>
+아래의 다이어그램은 매니페스트 파일의 일반적인 구조와 매니페스트 파일에
+들어있을 수 있는 모든 요소를 표시한 것입니다. 각 요소와 각각의 속성을 모두 문서화한
+전문은 별도의 파일에서 확인하실 수 있습니다. 어떤 요소에 대해서든
+상세한 정보를 보려면 다이어그램에서 해당 요소 이름을 클릭하십시오.
+이름은 다이어그램 뒤에 나오는 요소 목록(알파벳 순) 또는
+요소 이름이 언급되는 기타 영역 어디서든 클릭할 수 있습니다.
+</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration /&gt;</a> <!-- ##api level 3## -->
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature /&gt;</a> <!-- ##api level 4## -->
+ <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens /&gt;</a> <!-- ##api level 4## -->
+ <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">&lt;compatible-screens /&gt;</a> <!-- ##api level 9## -->
+ <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">&lt;supports-gl-texture /&gt;</a> <!-- ##api level 11## -->
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;/activity&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;/activity-alias&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data/&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;/service&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;/receiver&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;/provider&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;/application&gt;</a>
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;/manifest&gt;</a>
+</pre>
+
+<p>
+매니페스트 파일에 표시될 수 있는 모든 요소는 아래에 알파벳 순서로
+목록으로 표시되어 있습니다. 합법적인 요소는 이들이 전부입니다. 개발자 나름대로 요소 또는 속성을
+추가해서는 안 됩니다.
+</p>
+
+<p style="margin-left: 2em">
+<code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code> <!-- ##api level 4## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code> <!-- ##api level 3## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code> <!-- ##api level 4## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code>
+</p>
+
+
+
+
+<h2 id="filec">파일 규칙</h2>
+
+<p>
+몇몇 규칙과 규정은 매니페스트 내의 모든 요소와 속성에 전반적으로
+적용됩니다.
+</p>
+
+<dl>
+<dt><b>요소</b></dt>
+<dd>필수 요소는
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> 및
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> 요소뿐으로,
+이들은 각기 따로 표시되어야 하며 한 번씩만 발생할 수 있습니다.
+나머지는 대부분 여러 번 발생할 수 있거나 전혀 발생하지 않기도 합니다. 다만,
+그 중 최소한 몇몇은 있어야 매니페스트가 무엇이든 의미 있는 작업을
+달성할 수 있습니다.
+
+<p>
+요소에 무엇이든 들어있기만 하면 다른 요소가 그 요소에 들어 있는 것입니다.
+모든 값은 요소 내의 문자 데이터로서가 아니라 속성을 통해 설정됩니다.
+</p>
+
+<p>
+같은 레벨에 있는 여러 요소는 보통 순서가 지정되지 않습니다. 예를 들어
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> 및
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+요소는 어떤 순서로든 서로 섞여도 됩니다 (이 규칙에서
+<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+요소는 예외입니다. 이것은
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>의 별칭이므로
+이를 반드시 따라야 합니다).
+</p></dd>
+
+<dt><b>속성</b></dt>
+<dd>공식적인 의미에서 모든 속성은 선택 항목입니다. 그러나, 요소가 목적을 달성하기
+위해서 반드시 지정되어야 하는 것이 몇 가지 있습니다. 관련 문서를
+지침으로 사용하십시오. 정말로 선택적인 속성의 경우, 기본 값을 언급하거나
+사양이 없으면 어떤 일이 벌어지는지 진술합니다.
+
+<p>루트
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+요소의 몇 가지 속성을 제외하고 모든 속성 이름은 {@code android:alwaysRetainTaskState} 접두사로 시작합니다.
+예를 들어, {@code android:}와 같습니다. 이 접두사는 범용이기 때문에
+속성을 이름으로 참조하는 경우 관련 문서가 이를 생략하는 경우가
+일반적입니다.</p></dd>
+
+<dt><b>클래스 이름 선언</b></dt>
+<dd>대다수의 요소가 Java 객체에 상응합니다. 여기에는
+애플리케이션 자체에 대한 요소가 포함되며(
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+요소), 그것의 주 구성 요소도 포함됩니다. 즉, 액티비티
+(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>),
+서비스
+(<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>),
+브로드캐스트 수신기
+(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>) 및
+콘텐츠 제공자
+(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>) 등이 이에 해당됩니다.
+
+<p>
+하위 클래스를 정의하는 경우 구성 요소 클래스
+({@link android.app.Activity}, {@link android.app.Service},
+{@link android.content.BroadcastReceiver} 및 {@link android.content.ContentProvider})는 거의 항상 이렇게 하게 되는데,
+이때 하위 클래스는 {@code name} 속성을 통해 선언됩니다. 이 이름에 반드시
+완전한 패키지 지정이 포함되어 있어야 합니다.
+예를 들어, {@link android.app.Service} 하위 클래스를 선언하려면 다음과 같이 할 수 있습니다.
+</p>
+
+<pre>&lt;manifest . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name="com.example.project.SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+그러나 일종의 줄임으로서 문자열의 첫 번째 글자가 마침표인 경우, 해당
+문자열은 애플리케이션의 패키지 이름에 추가됩니다(
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+요소의
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code>
+속성에서 지정한 바와 같이). 다음 할당은 위의 것과 같습니다.
+</p>
+
+<pre>&lt;manifest package="com.example.project" . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name=".SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+Android는 구성 요소를 시작할 때 이름이 명명된 하위 클래스의 인스턴스를 생성합니다.
+하위 클래스가 지정되지 않은 경우, 기본 클래스의 인스턴스를 생성합니다.
+</p></dd>
+
+<dt><b>여러 개의 값</b></dt>
+<dd>하나 이상의 값을 지정할 수 있는 경우, 해당 요소는
+한 요소 안에 여러 개의 값을 목록으로 표시하기보다 거의 항상 반복됩니다.
+예를 들어 한 인텐트 필터가 여러 개의 작업을 목록으로 표시할 수 있습니다.
+
+<pre>&lt;intent-filter . . . &gt;
+ &lt;action android:name="android.intent.action.EDIT" /&gt;
+ &lt;action android:name="android.intent.action.INSERT" /&gt;
+ &lt;action android:name="android.intent.action.DELETE" /&gt;
+ . . .
+&lt;/intent-filter&gt;</pre></dd>
+
+<dt><b>리소스 값</b></dt>
+<dd>몇몇 속성에는 사용자에게 표시될 수 있는 값이 있습니다. 예를 들어
+액티비티에 대한 레이블과 아이콘 등이 이에 해당됩니다. 이러한 속성의 값은
+지역화해야 하며 따라서 리소스나 테마에서 설정됩니다. 리소스
+값은 다음과 같은 형식으로 표현됩니다.</p>
+
+<p style="margin-left: 2em">{@code @[<i>패키지</i>:]<i>유형</i>:<i>이름</i>}</p>
+
+<p>
+여기에서 <i>패키지</i> 이름은 리소스가 애플리케이션과 같은 패키지에 있으면 생략할 수 있고,
+ <i>유형</i> 은 "문자열" 또는 "그릴 수 있음" 같은 리소스 유형입니다. 그리고
+ <i>이름</i> 은 특정 리소스를 식별하는 이름입니다.
+예:
+</p>
+
+<pre>&lt;activity android:icon="@drawable/smallPic" . . . &gt</pre>
+
+<p>
+테마에서 가져온 값도 비슷한 방식으로 표현되지만, 처음 부분에 '{@code ?}'를 사용합니다
+('{@code @}' 대신).
+</p>
+
+<p style="margin-left: 2em">{@code ?[<i>패키지</i>:]<i>유형</i>:<i>이름</i>}
+</p></dd>
+
+<dt><b>문자열 값</b></dt>
+<dd>속성 값이 문자열인 경우, 이중 백슬래시('{@code \\}')를 사용하여
+문자 이스케이프를 수행해야 합니다. 예를 들어 줄바꿈에는 {@code \\n},
+유니코드 문자에는 '{@code \\uxxxx}'를 쓰십시오.</dd>
+</dl>
+
+
+<h2 id="filef">파일 기능</h2>
+
+<p>
+다음 섹션에서는 Android 기능을 매니페스트 파일에 반영하는
+몇 가지 방식을 설명합니다.
+</p>
+
+
+<h3 id="ifs">인텐트 필터</h3>
+
+<p>
+애플리케이션의 핵심 구성 요소(액티비티, 서비스 및 브로드캐스트
+수신기)를 활성화하는 것은 <i>인텐트</i>입니다. 인텐트는
+원하는 작업을 설명하는 정보 묶음입니다({@link android.content.Intent} 객체).
+여기에는 작업을 수행할 데이터, 작업을 수행할 구성 요소의 카테고리와
+기타 관련 지침 등이 포함됩니다.
+Android는 인텐트에 응답할 적절한 구성 요소를 찾아 필요한 경우 구성 요소의
+새 인스턴스를 시작하고, 이것을 인텐트 객체에
+전달합니다.
+</p>
+
+<p>
+구성 요소는 자신의 능력을 알립니다. 즉, 자신이 응답할 수 있는
+인텐트 종류를 밝힙니다. 이때 사용하는 것이 <i>인텐트 필터</i>입니다. Android 시스템은
+구성 요소를 시작하기 전에 해당 구성 요소가 처리할 수 있는 인텐트에 대해 학습해야 하기 때문에,
+인텐트 필터는 매니페스트 파일에
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+요소로 지정됩니다. 구성 요소 하나에 필터는 얼마든지 있을 수 있으며, 각각 서로 다른 기능을
+설명하게 됩니다.
+</p>
+
+<p>
+대상 구성 요소를 명시적으로 지명하는 인텐트가 해당 구성 요소를 활성화합니다.
+필터는 아무런 역할을 하지 않습니다. 하지만 대상을 이름으로 지정하지 않는 인텐트의 경우에는
+자신이 구성 요소의 필터 중 하나를 통과할 수 있을 때에만 해당 구성 요소를 활성화할 수
+있습니다.
+</p>
+
+<p>
+인텐트 객체를 인텐트 필터에 대해 테스트하는 방법에 대한 자세한 방법은
+별도의 문서인
+<a href="{@docRoot}guide/components/intents-filters.html">인텐트
+및 인텐트 필터</a>를 참조하십시오.
+</p>
+
+
+<h3 id="iconlabel">아이콘 및 레이블</h3>
+
+<p>
+대다수의 요소에 {@code icon}과 {@code label} 속성이 있으며
+이것으로 사용자에게 표시될 수 있는 작은 아이콘과 텍스트 레이블을 나타냅니다. 몇몇 요소에는
+{@code description} 속성도 있어 좀 더 긴 설명 텍스트를 나타낼 수 있고, 이것 또한 화면에
+표시될 수 있습니다. 예를 들어
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소는 이와 같은 속성을 셋 모두 가지고 있어 사용자가 이를 요청한 애플리케이션에 대한
+권한을 허가할 것인지 여부를 물으면 해당 권한,
+권한의 이름과 그에 수반되는 내용에 대한 설명을
+사용자에게 표시할 수 있습니다.
+</p>
+
+<p>
+어떤 경우에든, 요소에서 설정된 아이콘과 레이블이 해당 컨테이너의 모든 하위 요소에 대한 기본
+{@code icon}과 {@code label} 설정이 됩니다.
+따라서
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+요소에서 설정된 아이콘과 레이블이 애플리케이션의 각 요소에 대한 기본 아이콘과 레이블입니다.
+이와 유사하게, 구성 요소에 대해 설정된 아이콘과 레이블이 &mdash; 예를 들어
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+요소 &mdash; 각 구성 요소의
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+요소에 대한 기본 설정입니다.
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+요소가 레이블을 설정하지만 액티비티와 그 인텐트 필터는 이를 설정하지 않는 경우,
+애플리케이션 레이블을 액티비티와 인텐트 필터 양쪽 모두의 레이블인 것으로
+취급합니다.
+</p>
+
+<p>
+인텐트 필터에 대해 설정된 아이콘과 레이블은 구성 요소가 사용자에게
+표시될 때마다 구성 요소를 나타내는 데 사용되며, 이는 필터가 알린 기능을
+충족하는 것입니다. 예를 들어
+"{@code android.intent.action.MAIN}" 및
+"{@code android.intent.category.LAUNCHER}"가 설정된 필터는
+액티비티를 애플리케이션을 초기화하는 주역으로 알립니다. 다시 말해,
+애플리케이션 시작 관리자에 표시되어야 하는 것이 됩니다. 따라서 필터에서 설정된 아이콘과 레이블이
+시작 관리자에 표시되는 아이콘과 레이블입니다.
+</p>
+
+
+<h3 id="perms">권한</h3>
+
+<p>
+통상 <i>권한</i> 이란 기기에서 코드의 일부분 또는 데이터에 대한 액세스를 한정하는
+제한입니다. 이런 한계를 부과하는 것은 중요한 데이터와 코드를 보호하여
+이들이 남용되어서 사용자 환경을 왜곡하거나 손상시키지 않도록 하기 위해서입니다.
+</p>
+
+<p>
+각 권한은 고유한 레이블로 식별할 수 있습니다. 레이블을 보면 자신이 어떤 작업을 제한하는지
+나타내는 경우가 잦습니다. 예를 들어 다음은 Android가 정의하는 몇 가지 권한을 나타낸
+것입니다.
+</p>
+
+<p style="margin-left: 2em">{@code android.permission.CALL_EMERGENCY_NUMBERS}
+<br/>{@code android.permission.READ_OWNER_DATA}
+<br/>{@code android.permission.SET_WALLPAPER}
+<br/>{@code android.permission.DEVICE_POWER}</p>
+
+<p>
+하나의 기능을 보호하는 데에는 권한 하나면 충분합니다.
+</p>
+
+<p>
+애플리케이션에서 권한으로 보호하는 기능에 액세스해야 하는 경우,
+해당 권한이 필요하다고 매니페스트의
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+요소로 선언해야 합니다. 그런 다음, 해당 애플리케이션이 기기에 설치되고 나면
+설치 관리자가 요청한 권한을 허가할지 여부를 판별합니다.
+이때 애플리케이션의 인증서를 서명한 권한을 확인하고 어떤 경우에는 사용자에게
+묻기도 합니다.
+권한이 허가되면 해당 애플리케이션은 보호된 기능을 사용할 수
+있습니다. 허가되지 않으면, 그러한 기능에 액세스하려는 애플리케이션의 시도가 단순히 실패하고 사용자에게는
+아무런 알림도 표시되지 않습니다.
+</p>
+
+<p>
+애플리케이션은 권한을 사용하여 자신의 구성 요소를(액티비티, 서비스,
+브로드캐스트 수신기 및 콘텐츠 제공자) 보호할 수도 있습니다. Android가 정의한
+권한이라면 어떤 것이든 사용할 수 있고(
+{@link android.Manifest.permission android.Manifest.permission}에 목록으로 나열),
+아니면 다른 애플리케이션이 선언한 권한을 사용해도 됩니다. 아예 직접 자신만의 권한을 정의해도 됩니다. 새 권한을 선언할 때에는
+
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소를 사용합니다. 예를 들어 액티비티를 보호하려면 다음과 같이 하면 됩니다.
+</p>
+
+<pre>
+&lt;manifest . . . &gt;
+ &lt;permission android:name="com.example.project.DEBIT_ACCT" . . . /&gt;
+ &lt;uses-permission android:name="com.example.project.DEBIT_ACCT" /&gt;
+ . . .
+ &lt;application . . .&gt;
+ &lt;activity android:name="com.example.project.FreneticActivity"
+ android:permission="com.example.project.DEBIT_ACCT"
+ . . . &gt;
+ . . .
+ &lt;/activity&gt;
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+<p>
+이 예시에서는 {@code DEBIT_ACCT} 권한이
+
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소로 선언하였을 뿐만 아니라, 해당 권한의 사용 또한
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+요소로 요청되었다는 점을 눈여겨 보십시오. 이것의 사용을 요청해야 애플리케이션의 다른 구성 요소가 보호된
+액티비티를 시작할 수 있습니다. 이는 해당 보호를 애플리케이션 자신이 부과한 것이더라도
+관계 없이 적용됩니다.
+</p>
+
+<p>
+같은 예시에서, {@code permission} 속성이 다른 곳에서
+선언한 권한에 설정된 경우
+(예: {@code android.permission.CALL_EMERGENCY_NUMBERS}), 이것을
+
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소를 사용하여 다시 선언할 필요가 없습니다. 하지만 해당 권한의 사용은 여전히
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>로 요청해야 합니다.
+</p>
+
+<p>
+
+<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+요소는 코드로 정의될 권한 그룹에 대한 네임스페이스를
+선언합니다. 그리고
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+가 권한 집합에 대한 레이블을 정의합니다(매니페스트에
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소로 선언한 것과 다른 곳에서 선언한 것 양쪽 모두). 이것은 권한이 사용자에게 표시될 때
+그룹 지정될 방식에만 영향을 미칩니다.
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+요소는 그룹에 어느 권한이 속해 있는지 지정하는 것이 아니라, 그저
+그룹에 이름을 부여할 뿐입니다. 그룹에 권한을 배치하려면 그룹 이름을
+
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+요소의
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code>
+속성에 할당하면 됩니다.
+</p>
+
+
+<h3 id="libs">라이브러리</h3>
+
+<p>
+모든 애플리케이션은 기본 Android 라이브러리에 연결되어 있습니다. 여기에는
+애플리케이션 구축을 위한 기본적인 패키지(액티비티, 서비스,
+인텐트, 보기, 버튼, 애플리케이션, ContentProvider 등 보편적인 클래스 포함)가 포함되어
+있습니다.
+</p>
+
+<p>
+그러나 패키지 가운데에는 자신만의 라이브러리에 속한 것도 있습니다. 애플리케이션이
+사용하는 코드의 출처가 이러한 패키지 가운데 어느 한 가지에 해당되는 경우, 해당 패키지에 연결되도록
+명시적으로 요청해야만 합니다. 매니페스트에는 별도의
+<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+요소가 들어 있어 각 라이브러리의 이름을 나타내야 합니다 (라이브러리 이름은 패키지에 대한
+관련 문서에서 찾을 수 있습니다).
+</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/calendar-provider.jd b/docs/html-intl/intl/ko/guide/topics/providers/calendar-provider.jd
new file mode 100644
index 000000000000..4d69b6029ec4
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/calendar-provider.jd
@@ -0,0 +1,1184 @@
+page.title=캘린더 제공자
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#overview">기본 정보</a></li>
+ <li><a href="#manifest">사용자 권한</a></li>
+ <li><a href="#calendar">캘린더 테이블</a>
+<ol>
+ <li><a href="#query">캘린더 쿼리</a></li>
+ <li><a href="#modify-calendar">캘린더 수정</a></li>
+ <li><a href="#insert-calendar">캘린더 삽입</a></li>
+ </ol>
+ </li>
+ <li><a href="#events">이벤트 테이블</a>
+<ol>
+ <li><a href="#add-event">이벤트 추가</a></li>
+ <li><a href="#update-event">이벤트 업데이트</a></li>
+ <li><a href="#delete-event">이벤트 삭제</a></li>
+ </ol>
+ </li>
+ <li><a href="#attendees">참석자 테이블</a>
+<ol>
+ <li><a href="#add-attendees">참석자 추가</a></li>
+ </ol>
+ </li>
+ <li><a href="#reminders">알림 테이블</a>
+<ol>
+ <li><a href="#add-reminders">알림 추가</a></li>
+ </ol>
+ </li>
+ <li><a href="#instances">인스턴스 테이블</a>
+ <ol>
+ <li><a href="#query-instances">인스턴스 테이블 쿼리</a></li>
+ </ol></li>
+ <li><a href="#intents">캘린더 인텐트</a>
+ <ol>
+ <li><a href="#intent-insert">인텐트를 사용하여 이벤트 삽입</a></li>
+ <li><a href="#intent-edit">인텐트를 사용하여 이벤트 편집</a></li>
+ <li><a href="#intent-view">인텐트를 사용하여 캘린더 데이터 보기</a></li>
+ </ol>
+ </li>
+
+ <li><a href="#sync-adapter">동기화 어댑터</a></li>
+</ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.provider.CalendarContract.Calendars}</li>
+ <li>{@link android.provider.CalendarContract.Events}</li>
+ <li>{@link android.provider.CalendarContract.Attendees}</li>
+ <li>{@link android.provider.CalendarContract.Reminders}</li>
+ </ol>
+</div>
+</div>
+
+<p>캘린더 제공자는 사용자의 캘린더 이벤트를 저장하는 리포지토리입니다.
+캘린더 제공자 API를 사용하면 캘린더, 이벤트, 참석자, 알림 등의 쿼리, 삽입, 업데이트 및
+삭제 등의 작업을 수행할 수 있습니다.</p>
+
+
+<p>캘린더 제공자 API는 애플리케이션과 동기화 어댑터에서 사용할 수 있습니다.
+어떤 유형의 프로그램이 호출을 하는 주체인지에 따라 규칙이 각기 다릅니다.
+이 문서는 주로 캘린더 제공자 API를 애플리케이션으로 사용하는 것에 주안점을 두었습니다.
+여러 동기화 어댑터가 서로 어떻게 다른지 논의한 내용은
+<a href="#sync-adapter">동기화 어댑터</a>를 참조하십시오.</p>
+
+
+<p>캘린더 데이터를 읽거나 쓰려면 보통 애플리케이션의 매니페스트에
+적절한 권한이 포함되어 있어야 합니다. 이는 <a href="#manifest">사용자
+권한</a>에 설명되어 있습니다. 공통 작업을 쉽게 수행하기 위해 캘린더
+제공자는 <a href="#intents">캘린더
+인텐트</a>에 설명된 바와 같이 인텐트 집합을 제공합니다. 이와 같은 인텐트는 사용자를 캘린더 애플리케이션으로 이동시켜
+이벤트 삽입, 보기 및 편집을 할 수 있게 해줍니다. 사용자는 캘린더 애플리케이션과 상호 작용한 다음
+원래 애플리케이션으로 돌아옵니다. 따라서, 여러분의 애플리케이션이 이벤트를 보거나
+생성하기 위해 권한 허가를 요청할 필요도 없고 사용자 인터페이스를 제공할 필요도 없는 것입니다.</p>
+
+<h2 id="overview">기본 정보</h2>
+
+<p><a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a>는 데이터를 저장하여 애플리케이션에서
+이에 액세스할 수 있도록 합니다. 일반적으로, Android 플랫폼에서 제공하는 콘텐츠 제공자(캘린더 제공자 포함)는
+관계 데이터베이스 모델에 기초하여 테이블 집합으로 데이터를 노출합니다. 이 모델에서 각 행은 레코드이고,
+각 열은 특정한 유형과 의미를 가진 데이터입니다. 애플리케이션과 동기화 어댑터는
+캘린더 제공자 API를 통해 사용자의 캘린더 데이터를 보관하고 있는 데이터베이스 테이블에
+읽기/쓰기 액세스 권한을 얻을 수 있습니다.</p>
+
+<p>모든 콘텐츠 제공자는 데이터 세트를 고유하게 식별하는 공개 URI(
+{@link android.net.Uri}
+개체로 래핑됨)를 노출합니다. 여러 데이터 세트(여러 테이블)를 제어하는 콘텐츠 제공자는
+각 데이터 세트에 별도의 URI를 노출합니다.
+제공자에 대한 URI는 모두 문자열 "content://"로 시작합니다.
+이것을 보면 데이터를 콘텐츠 제공자가 제어하고 있다는 것을 알아볼 수 있습니다.
+캘린더 제공자가 각각의 클래스(테이블)에 대한 URI의 상수를 정의합니다.
+이와 같은 URI는 <code><em>&lt;class&gt;</em>.CONTENT_URI</code> 형식을 취합니다.
+예를 들면 다음과 같습니다. {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}</p>
+
+<p>그림 1은 캘린더 제공자 데이터 모델을 그림으로 나타낸 것입니다.
+이 그림에는 메인 테이블과이들을 서로 연결하는 필드가 표시되어 있습니다.</p>
+
+<img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model" />
+<p class="img-caption"><strong>그림 1.</strong> 캘린더 제공자 데이터 모델.</p>
+
+<p>한 사용자가 여러 개의 캘린더를 가질 수 있으며, 여러 가지 캘린더는 각기 다른 유형의 계정(Google 캘린더, Exchange 등)과 연결될 수 있습니다.</p>
+
+<p>{@link android.provider.CalendarContract}가 캘린더의 데이터 모델과 이벤트 관련 정보를 정의합니다. 이 데이터는 아래에 나열한 것과 같은 여러 테이블에 저장됩니다.</p>
+
+<table>
+ <tr>
+ <th>테이블(클래스)</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td><p>{@link android.provider.CalendarContract.Calendars}</p></td>
+
+ <td>이 테이블에는 캘린더별 정보가 담겨 있습니다.
+ 이 테이블의 행마다 한 캘린더의 세부 정보,
+예를 들어 이름, 색상, 동기화 정보 등이 들어갑니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Events}</td>
+
+ <td>이 테이블에는 이벤트별 정보가 담겨 있습니다.
+ 이 테이블의 행마다 한 이벤트의 세부 정보
+예를 들어 이벤트 제목, 위치, 시작 시간, 종료 시간 등의 정보가 들어갑니다.
+ 이벤트는 일회성일 수도 있고 여러 번 반복될 수도 있습니다.
+참석자, 알림 및 확장된 속성 등은 별도의 테이블에 저장됩니다.
+이들 테이블에는 각기 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}가 있어
+이벤트 테이블의 {@link android.provider.BaseColumns#_ID}를 참조합니다.</td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances}</td>
+
+ <td>이 테이블에는 각 이벤트 발생의 시작 시간과 종료 시간이
+담겨 있습니다. 이 테이블의 각 행이 하나의 이벤트 발생을 나타냅니다.
+ 일회성 이벤트의 경우, 이벤트에 대한 1:1 인스턴스 매핑이 있습니다.
+ 반복되는 이벤트의 경우, 해당 이벤트가 여러 번 발생하는 것에 맞추어
+자동으로 여러 행이 생성됩니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Attendees}</td>
+
+ <td>이 테이블에는 이벤트 참석자(게스트) 정보가 담겨 있습니다.
+ 각 행이 주어진 이벤트의 게스트 한 사람을 나타냅니다.
+ 이것이 게스트의 유형과, 이벤트에 대한 해당 게스트의 참석 여부 응답을
+나타냅니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Reminders}</td>
+
+ <td>이 테이블에는 경고/알림 데이터가 담겨 있습니다.
+ 각 행이 주어진 이벤트에 대한 경고 하나를 나타냅니다.
+이벤트 하나에 여러 개의 알림이 있을 수 있습니다. 이벤트당 최대 알림 개수는
+
+{@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS}에서 지정되고,
+이는 주어진 캘린더를 소유한 동기화 어댑터가 설정합니다.
+ 알림은 이벤트 몇 분 전에 지정되며 사용자에게 어떻게 경고할 것인지를
+결정하는 메서드를 가지고 있습니다.</td>
+ </tr>
+
+</table>
+
+<p>캘린더 제공자 API는 유연성과 강력함을 염두에 두고 만들어진 것입니다.
+그와 동시에 우수한 최종 사용자 경험을 제공하고 캘린더와 그 데이터의
+무결성을 보호하는 것 또한 중요합니다. 이를 위해서
+API를 사용할 때 유념해야 할 사항은 다음과 같습니다.</p>
+
+<ul>
+
+<li><strong>캘린더 이벤트 삽입, 업데이트 및 보기.</strong> 캘린더 제공자로부터 직접 이벤트를 삽입, 변경하고 읽으려면 적절한 <a href="#manifest">권한</a>이 필요합니다. 그러나, 완전한 캘린더 애플리케이션 또는 동기화 어댑터를 구축하는 경우가 아니라면 이와 같은 권한을 요청할 필요가 없습니다. 대신 Android의 캘린더 애플리케이션이 지원하는 인텐트를 사용하여 해당 애플리케이션에 읽기 및 쓰기 작업을 분배하면 됩니다. 인텐트를 사용하면, 애플리케이션이 사용자를 캘린더 애플리케이션으로 보내 사전에 작성된 양식으로 원하는 작업을
+수행하게 합니다. 작업이 끝나면 사용자는 애플리케이션으로 돌아옵니다.
+캘린더를 통해 공통 작업을 수행하도록 애플리케이션을 설계함으로써 사용자에게 일관되고 강력한
+사용자 인터페이스를 제공하는 것입니다. 이것이 권장 방법입니다.
+ 자세한 정보는 <a href="#intents">캘린더
+인텐트</a>를 참조하십시오.</p>
+
+
+<li><strong>동기화 어댑터.</strong>
+동기화 어댑터는 사용자의 기기에 있는 캘린더 데이터를 다른 서버 또는 데이터 소스와 동기화합니다.
+{@link android.provider.CalendarContract.Calendars}와
+{@link android.provider.CalendarContract.Events} 테이블에는
+동기화 어댑터가 사용하도록 예약된 열이 있습니다.
+제공자와 애플리케이션은 이를 수정해서는 안 됩니다. 사실, 동기화 어댑터로 액세스하지 않는 한
+이 열이 표시되지 않습니다.
+동기화 어댑터에 대한 자세한 정보는 <a href="#sync-adapter">동기화 어댑터</a>를 참조하십시오.</li>
+
+</ul>
+
+
+<h2 id="manifest">사용자 권한</h2>
+
+<p>캘린더 데이터를 읽으려면 애플리케이션의 매니페스트 파일에 {@link
+android.Manifest.permission#READ_CALENDAR} 권한이 포함되어 있어야 합니다.
+캘린더 데이터를 삭제, 삽입 또는 업데이트하려면{@link android.Manifest.permission#WRITE_CALENDAR}
+권한이 포함되어 있어야 합니다.</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;...&gt;
+ &lt;uses-sdk android:minSdkVersion=&quot;14&quot; /&gt;
+ &lt;uses-permission android:name=&quot;android.permission.READ_CALENDAR&quot; /&gt;
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_CALENDAR&quot; /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+
+<h2 id="calendar">캘린더 테이블</h2>
+
+<p>{@link android.provider.CalendarContract.Calendars}
+테이블에는 각각의 캘린더에 대한 세부 정보가 들어 있습니다.
+다음 캘린더 열은 애플리케이션과 <a href="#sync-adapter">동기화 어댑터</a> 모두 쓸 수 있는 것입니다.
+지원되는 필드의 전체 목록은
+{@link android.provider.CalendarContract.Calendars} 참조를 확인하십시오.</p>
+<table>
+ <tr>
+ <th>상수</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#NAME}</td>
+ <td>캘린더 이름입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td>
+ <td>사용자에게 표시되는 이 캘린더의 이름입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td>
+
+ <td>캘린더를 표시하기로 선택했는지를 나타내는 부울입니다.
+값이 0이면 이 캘린더와 연관된 이벤트는 표시하면 안 된다는 뜻입니다.
+ 값이 1이면 이 캘린더와 연관된 이벤트를 표시해야 한다는 뜻입니다.
+ 이 값이 {@link
+android.provider.CalendarContract.Instances} 테이블의 행 생성에 영향을 미칩니다.</td>
+
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td>
+
+ <td>캘린더를 동기화하고 이 캘린더의 이벤트를 기기에 저장해야할지를
+나타내는 부울입니다. 값이 0이면 이 캘린더를 동기화하거나 이에 속한 이벤트를
+기기에 저장하면 안 된다는 뜻입니다. 값이 1이면 이 캘린더에 대한 이벤트를 동기화하고 이에 속한
+이벤트를 기기에 저장하라는 뜻입니다.</td>
+ </tr>
+</table>
+
+<h3 id="query">캘린더 쿼리</h3>
+
+<p>다음은 특정한 사용자가 소유한 캘린더를 가져오는 법을 나타낸 예시입니다.
+ 이 예시에서는 단순하게 나타내기 위해 쿼리 작업을 사용자 인터페이스 스레드("주 스레드")에 표시했습니다.
+ 실제로는, 이 작업은 주 스레드 대신 비동기화 스레드에서 해야 합니다.
+ 자세한 논의는
+<a href="{@docRoot}guide/components/loaders.html">로더</a>를 참조하십시오. 데이터를 읽기만 하는 것이 아니라 변경도 하는 경우라면,
+{@link android.content.AsyncQueryHandler}를 참조하십시오.
+</p>
+
+
+<pre>
+// Projection array. Creating indices for this array instead of doing
+// dynamic lookups improves performance.
+public static final String[] EVENT_PROJECTION = new String[] {
+ Calendars._ID, // 0
+ Calendars.ACCOUNT_NAME, // 1
+ Calendars.CALENDAR_DISPLAY_NAME, // 2
+ Calendars.OWNER_ACCOUNT // 3
+};
+
+// The indices for the projection array above.
+private static final int PROJECTION_ID_INDEX = 0;
+private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
+private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
+private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;</pre>
+
+
+<div class="sidebox-wrapper"> <div class="sidebox"> <h3>
+ACCOUNT_TYPE을 반드시 포함시켜야 하는 이유는 무엇일까요?</h3> <p>{@link
+android.provider.CalendarContract.Calendars#ACCOUNT_NAME
+Calendars.ACCOUNT_NAME}에 대해 쿼리하는 경우, 해당 선택에
+{@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}
+도 포함시켜야 합니다. 이는 주어진 계정을 고유하다고 간주하는 것은 해당 계정의
+<code>ACCOUNT_NAME</code> 및
+<code>ACCOUNT_TYPE</code>이 모두 있을 때뿐이기 때문입니다. <code>ACCOUNT_TYPE</code>은 계정이
+
+{@link android.accounts.AccountManager}로 등록되었을 때 사용된 계정 인증자에 상응하는 문자열입니다. 기기와 연관되지 않은 캘린더에 적용되는 특별한 유형의 계정도 있으며 이를 {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}이라고 합니다.
+{@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} 계정은 동기화되지 않습니다.
+</p> </div> </div>
+
+
+<p> 다음 예시에서는 여러분이 직접 나름의 쿼리를 생성해보십시오. 선택 영역이 쿼리의 기준을 나타냅니다.
+ 이 예시에서 쿼리는
+<code>ACCOUNT_NAME</code>
+"sampleuser@google.com", <code>ACCOUNT_TYPE</code>
+"com.google" 및 <code>OWNER_ACCOUNT</code>
+"sampleuser@google.com"을 가지고 있는 캘린더를 찾고 있습니다. 사용자가 소유한 캘린더뿐만 아니라 사용자가 전에 본 캘린더까지 모두 확인하려면
+<code>OWNER_ACCOUNT</code>를 생략합니다.
+쿼리가 {@link android.database.Cursor}
+개체를 반환하여 이를 시용하면 데이터베이스 쿼리가 반환한 결과 집합을 트래버스할 수 있습니다.
+ 콘텐츠 제공자에서 쿼리를 사용하는 법에 대한 자세한 논의는
+<a href="{@docRoot}guide/topics/providers/content-providers.html">콘텐츠 제공자</a>를 참조하십시오.</p>
+
+
+<pre>// Run query
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+Uri uri = Calendars.CONTENT_URI;
+String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
+ + Calendars.ACCOUNT_TYPE + " = ?) AND ("
+ + Calendars.OWNER_ACCOUNT + " = ?))";
+String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google",
+ "sampleuser@gmail.com"};
+// Submit the query and get a Cursor object back.
+cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre>
+
+<p>다음에 표시된 섹션에서는 커서를 사용하여 결과 집합을 단계별로 살펴봅니다.
+여기에서는 예시의 시작 부분에서 설정된 상수를 사용하여 각 필드에 대한 값을 반환합니다.
+</p>
+
+<pre>// Use the cursor to step through the returned records
+while (cur.moveToNext()) {
+ long calID = 0;
+ String displayName = null;
+ String accountName = null;
+ String ownerName = null;
+
+ // Get the field values
+ calID = cur.getLong(PROJECTION_ID_INDEX);
+ displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
+ accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
+ ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
+
+ // Do something with the values...
+
+ ...
+}
+</pre>
+
+<h3 id="modify-calendar">캘린더 수정</h3>
+
+<p>캘린더 업데이트를 수행하려면 캘린더의 {@link
+android.provider.BaseColumns#_ID}를
+URI에 추가된 ID로
+
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}), 또는 첫 번째 선택 항목으로 제공하면 됩니다.
+
+선택은 <code>&quot;_id=?&quot;</code>로 시작해야 하며, 첫 번째
+<code>selectionArg</code>는 캘린더의 {@link
+android.provider.BaseColumns#_ID}여야 합니다.
+또한 ID를 URI에 인코딩해서도 업데이트를 수행할 수 있습니다. 이 예시에서는 캘린더의 표시 이름을
+
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})
+방식으로 변경하였습니다.</p>
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long calID = 2;
+ContentValues values = new ContentValues();
+// The new display name for the calendar
+values.put(Calendars.CALENDAR_DISPLAY_NAME, &quot;Trevor's Calendar&quot;);
+Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);</pre>
+
+<h3 id="insert-calendar">캘린더 삽입</h2>
+
+<p>캘린더는 주로 동기화 어댑터가 관리하도록 설계되어 있습니다. 따라서 새 캘린더는
+동기화 어댑터로서만 삽입해야 합니다. 대다수의 경우 애플리케이션은 캘린더에
+표면적인 사항만 변경할 수 있게 되어 있습니다(예: 표시 이름 변경 등).
+어떤 애플리케이션이 로컬 캘린더를 생성해야 하는 경우, 캘린더 삽입을 동기화 어댑터로 수행하면 됩니다.
+이때 {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}의 {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE}을 사용합니다.
+{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}
+은 기기 계정과 연관되지 않은 캘린더에 적용되는 특별한 유형의 계정입니다.
+ 이 유형의 캘린더는 서버에 동기화되지 않습니다.
+동기화 어댑터에 대한 논의는 <a href="#sync-adapter">동기화 어댑터</a>를 참조하십시오.</p>
+
+<h2 id="events">이벤트 테이블</h2>
+
+<p>{@link android.provider.CalendarContract.Events}
+테이블에는 각각의 이벤트에 대한 세부 정보가 들어 있습니다. 이벤트를 추가, 업데이트 또는 삭제하려면 애플리케이션의
+<a href="#manifest">매니페스트 파일</a>에 {@link android.Manifest.permission#WRITE_CALENDAR}
+권한이 포함되어 있어야 합니다.</p>
+
+<p>다음 이벤트 열은 애플리케이션과
+동기화 어댑터 모두 쓸 수 있는 것입니다. 지원되는 필드의 전체 목록은 {@link
+android.provider.CalendarContract.Events} 참조를 확인하십시오.</p>
+
+<table>
+ <tr>
+ <th>상수</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td>
+ <td>이벤트가 속한 캘린더의 {@link android.provider.BaseColumns#_ID}입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td>
+ <td>이벤트 조직자(소유자)의 이메일입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td>
+ <td>이벤트 제목입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td>
+ <td>이벤트가 일어나는 장소입니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td>
+ <td>이벤트 설명입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td>
+ <td>이벤트가 시작되는 시간을 Epoch 이후 UTC 밀리초 단위로 나타낸 것입니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td>
+ <td>이벤트가 종료되는 시간을 Epoch 이후 UTC 밀리초 단위로 나타낸 것입니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td>
+ <td>이벤트의 표준 시간대입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td>
+ <td>이벤트 종료 시간의 표준 시간대입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td>
+
+ <td>이벤트 기간을 <a href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a> 형식으로 나타낸 것입니다.
+예를 들어 <code>&quot;PT1H&quot;</code> 값을 보면 이벤트가 한 시간 지속될 것임을 알 수 있고,
+<code>&quot;P2W&quot;</code>는 2주의 지속 기간을 나타냅니다.
+ </td>
+
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td>
+
+ <td>값이 1이면 이 이벤트가 현지 시간대에서 정의한 바에 의해 하루 종일 걸린다는 것을 나타냅니다.
+ 값이 0이면 이것이 하루 중 언제라도 시작하고 종료될 수 있는 정기 이벤트라는 것을 나타냅니다.
+</td>
+
+
+ </tr>
+
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td>
+
+ <td>이벤트 형식의 반복 규칙입니다.
+예를 들면 다음과 같습니다. <code>&quot;FREQ=WEEKLY;COUNT=10;WKST=SU&quot;</code> 더 많은 예시를 확인하려면
+<a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">여기</a>를 참조하십시오.</td>
+
+ </tr>
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td>
+ <td>이벤트의 반복 날짜입니다.
+일반적으로 {@link android.provider.CalendarContract.EventsColumns#RDATE}
+를 {@link android.provider.CalendarContract.EventsColumns#RRULE}
+과 함께 사용하여 반복되는 발생의 집계 집합을 정의하게 됩니다.
+ 자세한 논의는 <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">RFC5545 사양</a>을 참조하십시오.</td>
+</tr>
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td>
+
+ <td>이 이벤트가 사용 중인 시간으로 간주되는지, 다시 일정을 예약할 수 있는 자유 시간으로 간주되는지를 나타냅니다.
+ </td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td>
+ <td>게스트가 이벤트를 수정할 수 있는지를 나타냅니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td>
+ <td>게스트가 다른 게스트를 초대할 수 있는지를 나타냅니다. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td>
+ <td>게스트가 참석자 목록을 볼 수 있는지를 나타냅니다.</td>
+ </tr>
+</table>
+
+<h3 id="add-event">이벤트 추가</h3>
+
+<p>애플리케이션이 새 이벤트를 추가하는 경우,
+{@link android.content.Intent#ACTION_INSERT INSERT} 인텐트를 사용하는 것이 좋습니다. 이때 <a href="#intent-insert">인텐트를 사용하여 이벤트 삽입</a>에서 설명한 대로 따릅니다. 그러나, 필요한 경우 직접 이벤트를 삽입해도 됩니다.
+ 이 섹션에서는 이렇게 하는 방법을 설명합니다.
+</p>
+
+
+<p>다음은 새 이벤트를 삽입할 때 따라야 하는 규칙입니다. </p>
+<ul>
+
+ <li>{@link
+android.provider.CalendarContract.EventsColumns#CALENDAR_ID}와 {@link
+android.provider.CalendarContract.EventsColumns#DTSTART}를 포함해야 합니다.</li>
+
+<li>{@link
+android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}을 포함해야 합니다.
+시스템에 설치된 표준 시간대 ID 목록을 가져오려면 {@link
+java.util.TimeZone#getAvailableIDs()}를 사용하십시오. 이 규칙은 <a href="#intent-insert">인텐트를 사용하여 이벤트 삽입</a>에서 설명한 바와 같이
+{@link
+android.content.Intent#ACTION_INSERT INSERT} 인텐트를 통해서 이벤트를 삽입할 경우에는 적용되지 않습니다. 이 시나리오의 경우,
+기본 시간대가 제공됩니다.</li>
+
+ <li>비반복적인 이벤트의 경우, {@link
+android.provider.CalendarContract.EventsColumns#DTEND}를 포함해야 합니다. </li>
+
+
+ <li>반복적인 이벤트의 경우 {@link
+android.provider.CalendarContract.EventsColumns#DURATION}과 {@link
+android.provider.CalendarContract.EventsColumns#RRULE} 또는 {@link
+android.provider.CalendarContract.EventsColumns#RDATE}를 포함해야 합니다. 이 규칙은 <a href="#intent-insert">인텐트를 사용하여 이벤트 삽입</a>에서 설명한 바와 같이
+{@link
+android.content.Intent#ACTION_INSERT INSERT} 인텐트를 통해서 이벤트를 삽입할 경우에는 적용되지 않습니다.
+이 시나리오에서는 {@link android.provider.CalendarContract.EventsColumns#DTSTART} 및 {@link android.provider.CalendarContract.EventsColumns#DTEND}와 함께 {@link
+android.provider.CalendarContract.EventsColumns#RRULE}를 사용할 수 있고, 캘린더 애플리케이션이 이것을 기간으로 자동 변환해줍니다.
+</li>
+
+</ul>
+
+<p>다음은 이벤트 삽입의 예입니다. 단순하게 나타내기 위해 UI 스레드에서 수행한 것입니다.
+ 실제로, 삽입과 업데이트는 비동기화 스레드에서 수행해야 작업을 배경 스레드로 이동시킬 수 있습니다.
+
+자세한 정보는 {@link android.content.AsyncQueryHandler}를 참조하십시오.</p>
+
+
+<pre>
+long calID = 3;
+long startMillis = 0;
+long endMillis = 0;
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 9, 14, 7, 30);
+startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 9, 14, 8, 45);
+endMillis = endTime.getTimeInMillis();
+...
+
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Events.DTSTART, startMillis);
+values.put(Events.DTEND, endMillis);
+values.put(Events.TITLE, &quot;Jazzercise&quot;);
+values.put(Events.DESCRIPTION, &quot;Group workout&quot;);
+values.put(Events.CALENDAR_ID, calID);
+values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
+Uri uri = cr.insert(Events.CONTENT_URI, values);
+
+// get the event ID that is the last element in the Uri
+long eventID = Long.parseLong(uri.getLastPathSegment());
+//
+// ... do something with event ID
+//
+//</pre>
+
+<p class="note"><strong>참고:</strong> 이벤트가 생성된 다음 이 예시가 이벤트 ID를 캡처하는 법을 눈여겨 보십시오.
+ 이것이 이벤트 ID를 가져오는 가장 쉬운 방법입니다.
+다른 캘린더 작업을 수행하기 위해 이벤트 ID가 필요한 경우가 자주 있습니다. 예를 들어 이벤트에 참석자나 알림을 추가하는 데 필요합니다.
+</p>
+
+
+<h3 id="update-event">이벤트 업데이트</h3>
+
+<p>애플리케이션이 사용자에게 이벤트 편집을 허용할 경우, <a href="#intent-edit">인텐트로 이벤트 편집</a>에서 설명한 바와 같이
+{@link android.content.Intent#ACTION_EDIT EDIT} 인텐트
+를 사용하는 것이 좋습니다.
+그러나 필요한 경우 직접 이벤트를 편집해도 됩니다.
+이벤트 업데이트를 수행하려면 이벤트의 <code>_ID</code>를 URI에 추가된 ID로({@link
+android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})
+또는 첫 번째 선택 항목으로 제공하면 됩니다.
+
+선택은 <code>&quot;_id=?&quot;</code>로 시작해야 하며, 첫 번째
+<code>selectionArg</code>는 이벤트의 <code>_ID</code>여야 합니다.
+ID 없이 선택을 사용해도 업데이트를 수행할 수 있습니다. 다음은 이벤트 업데이트의 예입니다.
+ 여기에서는 이벤트 제목을 변경할 때
+{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}
+ 방법을 사용합니다.</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 188;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri updateUri = null;
+// The new title for the event
+values.put(Events.TITLE, &quot;Kickboxing&quot;);
+updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows); </pre>
+
+<h3 id="delete-event">이벤트 삭제</h3>
+
+<p>이벤트를 삭제하려면 이벤트의 {@link
+android.provider.BaseColumns#_ID}를 URI에 추가된 ID로 써도 되고, 표준 선택을 사용해도 됩니다.
+ 추가된 ID를 사용하는 경우, 선택도 할 수 없습니다.
+삭제에는 두 가지 버전이 있습니다. 애플리케이션으로 삭제와 동기화 어댑터로의 삭제입니다.
+애플리케이션 삭제의 경우 <em>삭제된</em> 열을 1로 설정합니다.
+이것은 동기화 어댑터에 행이 삭제되었다고 알리는 플래그이며,
+이 삭제를 서버에 알려야 한다는 것을 나타내기도 합니다.
+동기화 어댑터 삭제의 경우, 이벤트를 연관된 데이터 일체와 함께 데이터베이스에서 제거합니다.
+다음은 애플리케이션이 이벤트를 {@link android.provider.BaseColumns#_ID}를 통해 삭제하는 예입니다.</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 201;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri deleteUri = null;
+deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().delete(deleteUri, null, null);
+Log.i(DEBUG_TAG, &quot;Rows deleted: &quot; + rows);
+</pre>
+
+<h2 id="attendees">참석자 테이블</h2>
+
+<p>{@link android.provider.CalendarContract.Attendees} 테이블의 각 행은
+이벤트의 참석자 또는 게스트 하나를 나타냅니다.
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()}
+를호출하면 주어진
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}와 함께 해당 이벤트의 참석자 목록을 반환합니다.
+이 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}는
+ 특정 이벤트의 {@link
+android.provider.BaseColumns#_ID}와 반드시 일치해야 합니다.</p>
+
+<p>다음 표는 쓸 수 있는 필드를 목록으로 나열한 것입니다.
+ 새 참석자를 삽입하는 경우 이 모두를 포함해야 하며,
+단 <code>ATTENDEE_NAME</code>은 예외입니다.
+</p>
+
+
+<table>
+ <tr>
+ <th>상수</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td>
+ <td>이벤트 ID입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td>
+ <td>참석자 이름입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td>
+ <td>참석자 이메일 주소입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td>
+ <td><p>참석자와 이벤트의 관계입니다. 다음 중 하나로 정해집니다.</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td>
+ <td><p>참석자 유형입니다. 다음 중 하나로 정해집니다. </p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td>
+ <td><p>참석자의 참석 상태입니다. 다음 중 하나로 정해집니다.</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li>
+ </ul></td>
+ </tr>
+</table>
+
+<h3 id="add-attendees">참석자 추가</h3>
+
+<p>다음은 이벤트에 참석자 한 명을 추가하는 예입니다.
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}
+가 필수인 점을 유념하십시오.</p>
+
+<pre>
+long eventID = 202;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Attendees.ATTENDEE_NAME, &quot;Trevor&quot;);
+values.put(Attendees.ATTENDEE_EMAIL, &quot;trevor@example.com&quot;);
+values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
+values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
+values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
+values.put(Attendees.EVENT_ID, eventID);
+Uri uri = cr.insert(Attendees.CONTENT_URI, values);
+</pre>
+
+<h2 id="reminders">알림 테이블</h2>
+
+<p>{@link android.provider.CalendarContract.Reminders}
+테이블의 각 행은 이벤트의 알림 하나를 나타냅니다.
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} 를 호출하면
+
+주어진 {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}와 함께 이벤트 알림 목록을 반환합니다.</p>
+
+
+<p>다음 표는 알림의 쓸 수 있는 필드를 목록으로 나열한 것입니다. 새 알림을 삽입하는 경우 이 모두를 포함해야 합니다.
+ 동기화 어댑터가 {@link
+android.provider.CalendarContract.Calendars} 테이블에서 지원하는 알림을 나타낸다는 점을 눈여겨 보십시오.
+ 자세한 내용은
+{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS}
+를 참조하십시오.</p>
+
+
+<table>
+ <tr>
+ <th>상수</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td>
+ <td>이벤트 ID입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td>
+ <td>이벤트 몇 분 전에 알림을 보내야 하는지 나타냅니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td>
+ <td><p>알림 메서드이며, 서버에서 설정한 대로 따릅니다. 다음 중 하나로 정해집니다.</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li>
+ </ul></td>
+ </tr>
+</table>
+
+<h3 id="add-reminders">알림 추가</h3>
+
+<p>이 예시는 이벤트에 알림을 추가하는 것입니다. 알림이 이벤트 15분 전에 발송됩니다.
+</p>
+<pre>
+long eventID = 221;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Reminders.MINUTES, 15);
+values.put(Reminders.EVENT_ID, eventID);
+values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
+Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre>
+
+<h2 id="instances">인스턴스 테이블</h2>
+
+<p>
+{@link android.provider.CalendarContract.Instances} 테이블에는
+이벤트 발생의 시작 및 종료 시간이 담겨 있습니다. 이 테이블의 각 행이 하나의 이벤트 발생을 나타냅니다.
+ 이 인스턴스 테이블은 쓸 수 없으며 이벤트 발생 쿼리 방법을 제공할 뿐입니다.
+ </p>
+
+<p>다음 표에는 인스턴스에 대해 쿼리할 수 있는 몇 가지 필드를 목록으로 나열하였습니다.
+표준 시간대가
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE}
+ 및
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES}에 의해 정의된다는 점을 눈여겨 보십시오.</p>
+
+
+<table>
+ <tr>
+ <th>상수</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td>
+ <td>인스턴스 시작 시간을 UTC 밀리초로 나타낸 것입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END}</td>
+ <td>인스턴스 종료 시간을 UTC 밀리초로 나타낸 것입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td>
+
+ <td>인스턴스의 율리우스력 종료 날짜를 캘린더의 시간대에 비례하여 나타낸 것입니다.
+
+
+</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td>
+
+ <td>인스턴스의 종료 시간(분 단위)을 캘린더 시간대의 자정부터 측정한 것입니다.
+</td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td>
+ <td>이 인스턴스에 대한 이벤트의 <code>_ID</code>입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td>
+ <td>인스턴스의 율리우스력 시작 날짜를 캘린더의 시간대에 비례하여 나타낸 것입니다.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td>
+
+ <td>인스턴스의 시작 시간(분 단위)을 캘린더 시간대에 비례하여 자정부터 측정한 것입니다.
+
+</td>
+
+ </tr>
+
+</table>
+
+<h3 id="query-instances">인스턴스 테이블 쿼리</h3>
+
+<p>인스턴스 테이블을 쿼리하려면, 해당 쿼리에 대한 범위 시간을 URI에 지정해야 합니다.
+ 이 예시에서는 {@link android.provider.CalendarContract.Instances}
+가 {@link
+android.provider.CalendarContract.EventsColumns#TITLE} 필드에 액세스 권한을 얻으며, 이때
+{@link android.provider.CalendarContract.EventsColumns} 인터페이스의 구현을 통합니다.
+바꿔 말하면, {@link
+android.provider.CalendarContract.EventsColumns#TITLE}이
+데이터베이스 보기를 통해 반환되며 원시 {@link
+android.provider.CalendarContract.Instances} 테이블 쿼리를 통해서가 아니라는 뜻입니다.</p>
+
+<pre>
+private static final String DEBUG_TAG = "MyActivity";
+public static final String[] INSTANCE_PROJECTION = new String[] {
+ Instances.EVENT_ID, // 0
+ Instances.BEGIN, // 1
+ Instances.TITLE // 2
+ };
+
+// The indices for the projection array above.
+private static final int PROJECTION_ID_INDEX = 0;
+private static final int PROJECTION_BEGIN_INDEX = 1;
+private static final int PROJECTION_TITLE_INDEX = 2;
+...
+
+// Specify the date range you want to search for recurring
+// event instances
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2011, 9, 23, 8, 0);
+long startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2011, 10, 24, 8, 0);
+long endMillis = endTime.getTimeInMillis();
+
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+
+// The ID of the recurring event whose instances you are searching
+// for in the Instances table
+String selection = Instances.EVENT_ID + " = ?";
+String[] selectionArgs = new String[] {"207"};
+
+// Construct the query with the desired date range.
+Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
+ContentUris.appendId(builder, startMillis);
+ContentUris.appendId(builder, endMillis);
+
+// Submit the query
+cur = cr.query(builder.build(),
+ INSTANCE_PROJECTION,
+ selection,
+ selectionArgs,
+ null);
+
+while (cur.moveToNext()) {
+ String title = null;
+ long eventID = 0;
+ long beginVal = 0;
+
+ // Get the field values
+ eventID = cur.getLong(PROJECTION_ID_INDEX);
+ beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
+ title = cur.getString(PROJECTION_TITLE_INDEX);
+
+ // Do something with the values.
+ Log.i(DEBUG_TAG, "Event: " + title);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(beginVal);
+ DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
+ Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));
+ }
+ }</pre>
+
+<h2 id="intents">캘린더 인텐트</h2>
+<p>캘린더 데이터를 읽고 쓰려면 애플리케이션에 <a href="#manifest">권한</a>이 없어도 됩니다. 대신 Android의 캘린더 애플리케이션이 지원하는 인텐트를 사용하여 해당 애플리케이션에 읽기 및 쓰기 작업을 분배하면 됩니다. 다음 표는 캘린더 제공자가 지원하는 인텐트를 목록으로 나열한 것입니다.</p>
+<table>
+ <tr>
+ <th>동작</th>
+ <th>URI</th>
+
+ <th>설명</th>
+ <th>추가</th>
+ </tr>
+ <tr>
+ <td><br>
+ {@link android.content.Intent#ACTION_VIEW VIEW} <br></td>
+ <td><p><code>content://com.android.calendar/time/&lt;ms_since_epoch&gt;</code></p>
+
+{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI}로도 URI를 참조할 수 있습니다.
+이 인텐트 사용법의 예시를 보려면 <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">인텐트를 사용하여 캘린더 데이터 보기</a>를 참조하십시오.
+
+ </td>
+ <td>캘린더를 <code>&lt;ms_since_epoch&gt;</code>에 의해 지정된 시간으로 엽니다.</td>
+ <td>없음.</td>
+ </tr>
+ <tr>
+ <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p>
+
+ </td>
+ <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+
+
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}로도 URI를 참조할 수 있습니다.
+이 인텐트 사용법의 예시를 보려면 <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">인텐트를 사용하여 캘린더 데이터 보기</a>를 참조하십시오.
+
+ </td>
+ <td><code>&lt;event_id&gt;</code>에 의해 지정된 이벤트를 봅니다.</td>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+ <br>
+ <br>
+ {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td>
+ <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+
+
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}로도 URI를 참조할 수 있습니다.
+이 인텐트 사용법의 예시를 보려면 <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">인텐트를 사용하여 이벤트 편집</a>을 참조하십시오.
+
+
+ </td>
+ <td><code>&lt;event_id&gt;</code>에 의해 지정된 이벤트를 편집합니다.</td>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+ <br>
+ <br>
+ {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br>
+ <br>
+ {@link android.content.Intent#ACTION_INSERT INSERT} </td>
+ <td><p><code>content://com.android.calendar/events</code></p>
+
+
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}로도 URI를 참조할 수 있습니다.
+이 인텐트 사용법의 예시를 보려면 <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">인텐트를 사용하여 이벤트 삽입</a>을 참조하십시오.
+
+ </td>
+
+ <td>이벤트를 생성합니다.</td>
+ <td>아래 테이블에 목록으로 표시된 추가 사항 모두입니다.</td>
+ </tr>
+</table>
+
+<p>다음 표에는 캘린더 제공자가 지원하는 인텐트 추가 사항이 목록으로 나열되어 있습니다.
+</p>
+<table>
+ <tr>
+ <th>인텐트 추가 사항</th>
+ <th>설명</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td>
+ <td>이벤트의 이름입니다.</td>
+ </tr>
+ <tr>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME}</td>
+ <td>이벤트 시작 시간을 Epoch로부터 밀리초 단위로 나타낸 것입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME}</td>
+
+ <td>이벤트 종료 시간을 Epoch로부터 밀리초 단위로 나타낸 것입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY
+CalendarContract.EXTRA_EVENT_ALL_DAY}</td>
+
+ <td>이벤트가 종일 이벤트인지 나타내는 부울입니다. 값은
+<code>true</code> 또는 <code>false</code>가 될 수 있습니다.</td> </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION
+Events.EVENT_LOCATION}</td>
+
+ <td>이벤트 위치입니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION
+Events.DESCRIPTION}</td>
+
+ <td>이벤트 설명입니다.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td>
+ <td>초대할 사람의 이메일 주소를 쉼표로 구분한 목록입니다.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td>
+ <td>이벤트의 반복 규칙입니다.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL
+Events.ACCESS_LEVEL}</td>
+
+ <td>이벤트가 비공개인지 공개인지 나타냅니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY
+Events.AVAILABILITY}</td>
+
+ <td>이 이벤트가 사용 중인 시간으로 간주되는지, 다시 일정을 예약할 수 있는 자유 시간으로 간주되는지를 나타냅니다.</td>
+
+</table>
+<p>아래 섹션에서는 이와 같은 인텐트의 사용법을 설명합니다.</p>
+
+
+<h3 id="intent-insert">인텐트를 사용하여 이벤트 삽입</h3>
+
+<p>{@link android.content.Intent#ACTION_INSERT INSERT} 인텐트를 사용하면
+캘린더에 이벤트 삽입 작업을 분배할 수 있습니다.
+이 방법을 사용하는 경우, 애플리케이션의 <a href="#manifest">매니페스트 파일</a>에 {@link
+android.Manifest.permission#WRITE_CALENDAR} 권한을 포함할 필요가 없습니다.</p>
+
+
+<p>사용자가 이 방법을 사용하는 애플리케이션을 실행하면 해당 애플리케이션이
+사용자를 캘린더로 보내 이벤트 추가를 완료합니다. {@link
+android.content.Intent#ACTION_INSERT INSERT} 인텐트는 추가 필드를 사용하여
+캘린더에 있는 이벤트 세부 정보로 양식을 미리 채웁니다.
+그러면 사용자가 이벤트를 취소하거나 양식을 필요에 따라 편집할 수 있고,
+이벤트를 본인의 캘린더에 저장할 수도 있습니다.</p>
+
+
+
+<p>다음은 2012년 1월 19일에 이벤트 일정을 예약하는 코드 조각으로,
+이는 오전 7:30~오전 8:30까지 실행됩니다. 이 코드 조각에 관해서는 다음 내용을 주의하십시오.</p>
+
+<ul>
+ <li>이것은 {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}를 URI로 지정합니다.
+</li>
+
+ <li>이것은 {@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME} 및 {@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME} 추가 필드를 사용하여 이벤트 시간으로 양식을 미리 채웁니다.
+ 이러한 시간에 해당하는 값은 Epoch로부터 UTC 밀리초 단위로 표시해야 합니다.
+</li>
+
+ <li>이것은 {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}
+추가 필드를 사용하여 쉼표로 구분된 초청인 목록을 제공하며, 이는 이메일 주소로 나타납니다.</li>
+
+</ul>
+<pre>
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 0, 19, 8, 30);
+Intent intent = new Intent(Intent.ACTION_INSERT)
+ .setData(Events.CONTENT_URI)
+ .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
+ .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
+ .putExtra(Events.TITLE, &quot;Yoga&quot;)
+ .putExtra(Events.DESCRIPTION, &quot;Group class&quot;)
+ .putExtra(Events.EVENT_LOCATION, &quot;The gym&quot;)
+ .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
+ .putExtra(Intent.EXTRA_EMAIL, &quot;rowan@example.com,trevor@example.com&quot;);
+startActivity(intent);
+</pre>
+
+<h3 id="intent-edit">인텐트를 사용하여 이벤트 편집</h3>
+
+<p><a href="#update-event">이벤트 업데이트</a>에서 설명한 바와 같이 이벤트를 직접 업데이트할 수 있습니다. 그러나 {@link
+android.content.Intent#ACTION_EDIT EDIT} 인텐트를 사용하면
+캘린더 애플리케이션에 이벤트 편집을 분배할 권한이 없는 애플리케이션을 허용합니다.
+사용자가 캘린더에서 이벤트 편집을 마치면 원래 애플리케이션으로 돌아오게 됩니다.
+</p> <p>다음은 지정된 이벤트에 새 제목을 설정하여 사용자에게 캘린더에서 이벤트를 편집할 수 있도록 해주는 인텐트의 예입니다.
+</p>
+
+
+<pre>long eventID = 208;
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_EDIT)
+ .setData(uri)
+ .putExtra(Events.TITLE, &quot;My New Title&quot;);
+startActivity(intent);</pre>
+
+<h3 id="intent-view">인텐트를 사용하여 캘린더 데이터 보기</h3>
+<p>캘린더 제공자는 {@link android.content.Intent#ACTION_VIEW VIEW} 인텐트를 사용하는 두 가지 방식을 제공합니다.</p>
+<ul>
+ <li>캘린더를 특정 날짜에 여는 방식</li>
+ <li>이벤트를 보는 방식</li>
+
+</ul>
+<p>다음은 캘린더를 특정 날짜에 여는 방법을 보여주는 예입니다.</p>
+<pre>// A date-time specified in milliseconds since the epoch.
+long startMillis;
+...
+Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+builder.appendPath(&quot;time&quot;);
+ContentUris.appendId(builder, startMillis);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+ .setData(builder.build());
+startActivity(intent);</pre>
+
+<p>다음은 이벤트를 보기 위해 여는 방법을 나타낸 예입니다.</p>
+<pre>long eventID = 208;
+...
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+ .setData(uri);
+startActivity(intent);
+</pre>
+
+
+<h2 id="sync-adapter">동기화 어댑터</h2>
+
+
+<p>애플리케이션과 동기화 어댑터가 캘린더 제공자에 액세스하는 방식에는 사소한 차이만이 있을 뿐입니다.
+</p>
+
+<ul>
+ <li>동기화 어댑터는 {@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER}를 <code>true</code>로 설정하여 이것이 동기화 어댑터라는 것을 나타내야 합니다.</li>
+
+
+ <li>동기화 어댑터는 URI에서 쿼리 매개변수로 {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME}과 {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE}을 제공해야 합니다. </li>
+
+ <li>동기화 어댑터에는 애플리케이션 또는 위젯에 비해 더 많은 열에 대한 쓰기 액세스 권한이 있습니다.
+ 예를 들어, 애플리케이션은 캘린더의 몇 가지 특성만 수정할 수 있습니다.
+즉 이름, 표시 이름, 가시성 설정 및 캘린더 동기화 여부 등만 해당됩니다.
+ 이에 비해 동기화 어댑터의 경우 이 열만이 아니라 다른 수많은 열에도 액세스할 수 있습니다.
+예를 들어 캘린더 색상, 표준 시간대, 액세스 수준 등이 해당됩니다.
+다만, 동기화 어댑터는 지정된 <code>ACCOUNT_NAME</code> 및
+<code>ACCOUNT_TYPE</code>에 한정됩니다.</li> </ul>
+
+<p>다음은 URI를 반환하여 동기화 어댑터와 사용하도록 할 때 쓸 수 있는 도우미 메서드입니다.</p>
+<pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) {
+ return uri.buildUpon()
+ .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,&quot;true&quot;)
+ .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+ .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+ }
+</pre>
+<p>동기화 어댑터의 샘플 구현(캘린더에 구체적으로 관련된 것이 아님)은
+<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdpater</a>를 참조하십시오.
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/contacts-provider.jd b/docs/html-intl/intl/ko/guide/topics/providers/contacts-provider.jd
new file mode 100644
index 000000000000..94d3295c1d46
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/contacts-provider.jd
@@ -0,0 +1,2356 @@
+page.title=연락처 제공자
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<h2>간략히 보기</h2>
+<ul>
+ <li>사람들 관련 정보를 저장한 Android의 리포지토리입니다.</li>
+ <li>
+ 웹과 동기화합니다.
+ </li>
+ <li>
+ 소셜 스트림 데이터와 통합됩니다.
+ </li>
+</ul>
+<h2>이 문서의 내용</h2>
+<ol>
+ <li>
+ <a href="#InformationTypes">연락처 제공자 조직</a>
+ </li>
+ <li>
+ <a href="#RawContactBasics">원시 연락처</a>
+ </li>
+ <li>
+ <a href="#DataBasics">데이터</a>
+ </li>
+ <li>
+ <a href="#ContactBasics">연락처</a>
+ </li>
+ <li>
+ <a href="#Sources">동기화 어댑터의 데이터</a>
+ </li>
+ <li>
+ <a href="#Permissions">필수 권한</a>
+ </li>
+ <li>
+ <a href="#UserProfile">사용자 프로필</a>
+ </li>
+ <li>
+ <a href="#ContactsProviderMetadata">연락처 제공자 메타데이터</a>
+ </li>
+ <li>
+ <a href="#Access">연락처 제공자 액세스</a>
+ <li>
+ </li>
+ <li>
+ <a href="#SyncAdapters">연락처 제공자 동기화 어댑터</a>
+ </li>
+ <li>
+ <a href="#SocialStream">소셜 스트림 데이터</a>
+ </li>
+ <li>
+ <a href="#AdditionalFeatures">추가 연락처 제공자 기능</a>
+ </li>
+</ol>
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.provider.ContactsContract.Contacts}</li>
+ <li>{@link android.provider.ContactsContract.RawContacts}</li>
+ <li>{@link android.provider.ContactsContract.Data}</li>
+ <li>{@code android.provider.ContactsContract.StreamItems}</li>
+</ol>
+<h2>관련 샘플</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ 연락처 관리자
+ </a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ 샘플 동기화 어댑터</a>
+ </li>
+</ol>
+<h2>참고 항목</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ 콘텐츠 제공자 기본 정보
+ </a>
+ </li>
+</ol>
+</div>
+</div>
+<p>
+ 콘텐츠 제공자는 기기의 사람에 대한 중앙 데이터 리포지토리를 관리하는 강력하고 유연한
+Android 구성 요소입니다. 콘텐츠 제공자는 기기의 연락처 애플리케이션에서 개발자에게 표시되는
+데이터의 출처입니다. 여기의 데이터에는 개발자 자신의 애플리케이션에서
+액세스하여 기기와 온라인 서비스 사이에서 데이터를 전송할 수도 있습니다. 제공자는
+광범위한 데이터 소스를 수용하며 각 인물에 대해 가능한 한 많은 데이터를 관리하여야 하므로, 그 결과 조직이 무척
+복잡합니다. 이 때문에 이 제공자의 API에는
+광범위한 계약 클래스와 인터페이스 세트가 포함되어 있어 데이터 검색과 수정을 모두 한층
+용이하게 해줍니다.
+</p>
+<p>
+ 이 가이드에서 설명하는 내용은 다음과 같습니다.
+</p>
+ <ul>
+ <li>
+ 기본적인 제공자 구조.
+ </li>
+ <li>
+ 제공자에서 데이터를 검색하는 방법.
+ </li>
+ <li>
+ 제공자에서 데이터를 수정하는 방법.
+ </li>
+ <li>
+ 동기화 어댑터를 작성하여 서버에서 가져온 데이터를 연락처 제공자와
+동기화하는 방법.
+ </li>
+ </ul>
+<p>
+ 이 가이드는 독자가 Android 콘텐츠 제공자의 기본 정보를 알고 있는 것으로 간주합니다. Android 콘텐츠 제공자에
+관한 자세한 내용은
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+콘텐츠 제공자 기본 정보</a> 가이드를 읽어보십시오.
+<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">샘플 동기화 어댑터</a>
+샘플 앱은 동기화 어댑터를 사용하여 연락처 제공자와 Google Web Services가 호스팅하는 샘플 애플리케이션 사이에서
+데이터를 전송하는 동기화 어댑터의 사용 예시입니다.
+</p>
+<h2 id="InformationTypes">연락처 제공자 조직</h2>
+<p>
+ 연락처 제공자는 Android 콘텐츠 제공자 구성 요소입니다. 이것은 한 사람에 대해
+각기 세 가지 유형의 데이터를 관리합니다. 각 데이터는 그림 1에서 설명하는 바와 같이 제공자가 제공하는
+각 테이블에 상응합니다.
+</p>
+<img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" />
+<p class="img-caption">
+ <strong>그림 1.</strong> 연락처 제공자 테이블 구조입니다.
+</p>
+<p>
+ 이 세 개의 테이블은 보통 자신의 계약 클래스의 이름으로 불립니다. 이들 클래스는
+테이블에서 사용하는 콘텐츠 URI, 열 이름 및 열 값의 상수를 정의합니다.
+</p>
+<dl>
+ <dt>
+ {@link android.provider.ContactsContract.Contacts} 테이블
+ </dt>
+ <dd>
+ 행은 원시 연락처 행의 집계에 기초하여 각기 다른 사람을 나타냅니다.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.RawContacts} 테이블
+ </dt>
+ <dd>
+ 사용자 계정과 유형을 기준으로, 한 사람에 대한 데이터 요약이 들어있는 행입니다.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.Data} 테이블
+ </dt>
+ <dd>
+ 이메일 주소나 전화 번호와 같은 원시 연락처의 세부 정보가 들어있는 행입니다.
+ </dd>
+</dl>
+<p>
+ {@link android.provider.ContactsContract}의 계약 클래스가 대표하는 다른 테이블은
+보조 테이블로, 연락처 제공자는 이들을 사용하여 작업을 관리하거나 기기의 연락처에 있는
+특정 기능 또는 전화 통신 애플리케이션 등을 지원합니다.
+</p>
+<h2 id="RawContactBasics">원시 연락처</h2>
+<p>
+ 원시 연락처는 단일 계정 유형과 계정 이름에서 가져오는
+한 사람의 데이터를 나타냅니다. 연락처 제공자는 한 사람에 대해 하나 이상의 온라인 서비스를 데이터의 출처로 허용하므로,
+연락처 제공자에서는 같은 사람에 대해 여러 개의 원시 연락처를 허용합니다.
+ 원시 연락처를 여러 개 사용하면 사용자가 같은 계정 유형의 하나 이상의 계정에서 가져온
+한 사람의 여러 데이터를 조합할 수 있습니다.
+</p>
+<p>
+ 원시 연락처의 데이터 대부분은
+{@link android.provider.ContactsContract.RawContacts} 테이블에 저장되지 않습니다. 대신,
+{@link android.provider.ContactsContract.Data} 테이블에서 하나 이상의 행에 저장됩니다. 각 데이터 행에는
+상위 {@link android.provider.ContactsContract.RawContacts} 행의 {@code android.provider.BaseColumns#_ID RawContacts._ID} 값을 포함하는
+열 {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID}가
+있습니다.
+</p>
+<h3 id="RawContactsColumns">중요한 원시 연락처 열</h3>
+<p>
+ {@link android.provider.ContactsContract.RawContacts} 테이블의 중요한 열은
+표 1에 나열되어 있습니다. 표 뒤에 이어지는 참고 사항을 꼭 읽어주십시오.
+</p>
+<p class="table-caption" id="table1">
+ <strong>표 1.</strong> 중요한 원시 연락처 열입니다.
+</p>
+<table>
+ <tr>
+ <th scope="col">열 이름</th>
+ <th scope="col">용도</th>
+ <th scope="col">참고</th>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME}
+ </td>
+ <td>
+ 이 원시 연락처의 소스인 계정 유형에 대한 계정 이름입니다.
+ 예를 들어, Google 계정의 계정 이름은
+기기 소유자의 Gmail 주소 중 하나입니다. 자세한 정보는
+{@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}의
+다음 항목을 참조하십시오.
+ </td>
+ <td>
+ 이 이름의 형식은 각자의 계정 유형별로 다릅니다. 이것은 꼭
+이메일 주소여야 하는 것은 아닙니다.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}
+ </td>
+ <td>
+ 이 원시 연락처의 소스인 계정 유형입니다. 예를 들어, Google 계정의
+계정 유형은 <code>com.google</code>입니다. 계정 유형을 정규화할 때에는 항상
+본인이 소유하거나 제어하는 도메인의 도메인 식별자를 사용하십시오. 이렇게 하면 계정 유형이 고유한 것이도록
+확실히 해둘 수 있습니다.
+ </td>
+ <td>
+ 연락처 데이터를 제공하는 계정 유형은 대개 연락처 제공자와 동기화되는 동기화 어댑터와
+연관되어 있습니다.
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.RawContactsColumns#DELETED}
+ </td>
+ <td>
+ 원시 연락처에 대한 "삭제됨" 플래그입니다.
+ </td>
+ <td>
+ 이 플래그를 사용하면 연락처 제공자가 해당 행을 내부에 계속 유지할 수 있습니다.
+이는 동기화 어댑터가 해당 행을 자신의 서버에서 삭제하고 마침내는 행을 리포지토리에서도 삭제할 수 있을
+때까지만입니다.
+ </td>
+ </tr>
+</table>
+<h4>참고</h4>
+<p>
+ 다음은
+{@link android.provider.ContactsContract.RawContacts} 테이블에 관한 중요한 참고 사항입니다.
+</p>
+<ul>
+ <li>
+ 원시 연락처의 이름은
+{@link android.provider.ContactsContract.RawContacts}에 있는 자신의 행에 저장되지 않습니다. 대신,
+{@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 행에 있는
+{@link android.provider.ContactsContract.Data} 테이블에 저장됩니다. 원시 연락처 하나에는
+{@link android.provider.ContactsContract.Data} 테이블에서 이런 유형의 행이 하나씩만 있습니다.
+ </li>
+ <li>
+ <strong>주의:</strong> 원시 연락처에서 본인의 계정 데이터를 사용하려면 이를 우선
+{@link android.accounts.AccountManager}로 등록해야 합니다. 이렇게 하려면,
+사용자에게 계정 유형과 본인의 계정 이름을 계정 목록에 추가하라는 프롬프트를 표시하십시오. 이렇게 하지 않으면,
+연락처 제공자가 원시 연락처 행을 자동으로 삭제합니다.
+ <p>
+ 예를 들어, 앱에서 도메인 {@code com.example.dataservice}로 웹 베이스 서비스에 대한 연락처 데이터를 유지하고
+서비스에 대한 사용자 계정이
+{@code becky.sharp@dataservice.example.com}이라면, 사용자는 앱이 원시 연락처 행을 추가하기 전에
+계정 "유형"({@code com.example.dataservice})과 계정 "이름"
+({@code becky.smart@dataservice.example.com})을 먼저 추가해야 합니다.
+ 이 요구 사항을 사용자에게 설명하려면 관련 문서를 사용해도 되고, 아니면 사용자에게
+유형과 이름을 추가하라는 프롬프트를 표시해도 되고 두 가지 방법을 다 써도 됩니다. 계정 유형과 계정 이름은
+다음 섹션에서 더 자세히 설명되어 있습니다.
+ </li>
+</ul>
+<h3 id="RawContactsExample">원시 연락처 데이터 소스</h3>
+<p>
+ 원시 연락처의 작동 원리를 이해하기 위해, 다음과 같이 기기에서 정의한 사용자 계정 세 가지를 보유한 사용자 "Emily Dickinson"이 있다고
+가정해 봅시다.
+</p>
+<ul>
+ <li><code>emily.dickinson@gmail.com</code></li>
+ <li><code>emilyd@gmail.com</code></li>
+ <li>Twitter 계정 "belle_of_amherst"</li>
+</ul>
+<p>
+ 이 사용자는 <em>계정</em> 설정에서 모든 세 가지 계정에 대해 <em>연락처 동기화</em>를
+활성화했습니다.
+</p>
+<p>
+ Emily Dickinson이 브라우저 창을 열고,
+Gmail에 <code>emily.dickinson@gmail.com</code>으로 로그인하고,
+연락처를 열어서 "Thomas Higginson"을 추가한다고 가정하겠습니다. 이 사용자는 나중에 Gmail에
+<code>emilyd@gmail.com</code>으로 로그인하고 "Thomas Higginson"에게 이메일을 전송합니다.
+이렇게 하면 이 사람을 자동으로 연락처로 추가합니다. Emily는 Twitter에서 "colonel_tom"(Thomas Higginson의 Twitter ID)도
+팔로우합니다.
+</p>
+<p>
+ 연락처 제공자는 이 작업의 결과로 원시 연락처를 세 개 생성합니다.
+</p>
+<ol>
+ <li>
+ <code>emily.dickinson@gmail.com</code>과 연관된 "Thomas Higginson"의 원시 연락처입니다.
+ 사용자 계정 유형은 Google입니다.
+ </li>
+ <li>
+ <code>emilyd@gmail.com</code>과 연관된 "Thomas Higginson"의 두 번째 원시 연락처입니다.
+ 사용자 계정 유형은 마찬가지로 Google입니다. 이름이 이전 이름과 똑같더라도 두 번째 원시 연락처가
+더해집니다. 왜냐하면 이 사람은 아까와 다른
+사용자 계정에 추가되었기 때문입니다.
+ </li>
+ <li>
+ "belle_of_amherst"와 연관된 "Thomas Higginson"의 세 번째 원시 연락처입니다. 사용자
+계정 유형은 Twitter입니다.
+ </li>
+</ol>
+<h2 id="DataBasics">데이터</h2>
+<p>
+ 이전에 언급한 바와 같이, 원시 연락처의 데이터는
+원시 연락처의 <code>_ID</code> 값과 연결된{@link android.provider.ContactsContract.Data} 행에
+저장됩니다. 이렇게 하면 하나의 원시 연락처에 같은 유형의 데이터의 인스턴스가 여러 개 있을 수 있게 됩니다.
+예를 들어 이메일 주소 또는 전화 번호 등이 이에 해당됩니다. 예를 들어,
+{@code emilyd@gmail.com}에 대한 "Thomas Higginson"(Google 계정 <code>emilyd@gmail.com</code>과 연관된 Thomas Higginson의
+원시 연락처)에는
+<code>thigg@gmail.com</code>이라는 집 이메일 주소와
+<code>thomas.higginson@gmail.com</code>이라는 직장 이메일 주소가 있고, 연락처 제공자는 두 개의 이메일 주소 행을 저장하고
+원시 연락처에 두 가지를 연결합니다.
+</p>
+<p>
+ 이 테이블 하나에 여러 가지 유형의 데이터가 저장된 점에 주의하십시오. 표시 이름,
+전화 번호, 이메일, 우편 주소, 사진 및 웹사이트 세부 정보 행은 모두
+{@link android.provider.ContactsContract.Data} 테이블에서 찾을 수 있습니다. 이런 데이터 관리를 돕기 위해
+{@link android.provider.ContactsContract.Data} 테이블에는 설명이 포함된 이름이 있는 열이 몇 개 있고
+일반적 이름이 포함된 열도 몇 개 있습니다. 설명이 포함된 이름 열의 콘텐츠는 행 안의 데이터 유형과 관계 없이 모두 의미가 같고,
+일반적인 이름 열의 콘텐츠는 데이터 유형에 따라
+서로 의미가 다릅니다.
+</p>
+<h3 id="DescriptiveColumns">설명이 포함된 열 이름</h3>
+<p>
+ 다음은 설명이 포함된 열 이름의 몇 가지 예시입니다.
+</p>
+<dl>
+ <dt>
+ {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID}
+ </dt>
+ <dd>
+ 이 데이터에 대한 원시 연락처의 <code>_ID</code> 열 값입니다.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.Data#MIMETYPE}
+ </dt>
+ <dd>
+ 이 행에 저장되는 데이터 유형으로, 사용자 지정 MIME 유형으로 표현됩니다. 연락처 제공자는
+{@link android.provider.ContactsContract.CommonDataKinds}의 하위 클래스에서 정의된
+MIME 유형을 사용합니다. 이러한 MIME 유형은 오픈 소스이고,
+연락처 제공자와 함께 사용할 수 있는 모든 애플리케이션 또는 동기화 어댑터가 사용할 수 있습니다.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}
+ </dt>
+ <dd>
+ 이 유형의 데이터 행이 원시 연락처에서 한 번 이상 발생하는 경우,
+{@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 열은
+해당 유형의 기본 데이터가 들어있는 데이터 행을 플래그로 표시합니다. 예를 들어,
+사용자가 연락처의 전화 번호를 길게 누르고 <strong>기본값으로 설정</strong>을 선택하면
+그 번호가 들어있는 {@link android.provider.ContactsContract.Data} 행이
+{@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} 열을
+0이 아닌 값으로 설정합니다.
+ </dd>
+</dl>
+<h3 id="GenericColumns">일반 열 이름</h3>
+<p>
+ 15개의 일반 열 중에서 <code>DATA1</code>부터
+<code>DATA15</code>까지는 일반적으로 이용할 수 있고 이외에 추가로 마련된 네 개의 일반
+열, 즉 <code>SYNC1</code>부터 <code>SYNC4</code>까지는
+동기화 어댑터 전용입니다. 일반 열 이름 상수는 해당 행에 들어있는 데이터 유형과 관계 없이
+언제나 통합니다.
+</p>
+<p>
+ <code>DATA1</code> 열은 색인됩니다. 연락처 제공자는 제공자가 가장 자주 쿼리의 대상이 될 것으로 예상하는
+데이터에 대해 항상 이 열을 사용합니다. 예컨대
+이메일 행의 경우, 이 열에 실제 이메일 주소가 들어있습니다.
+</p>
+<p>
+ 규칙에 따라 열 <code>DATA15</code>는 사진 미리 보기와 같은 BLOB(Binary Large Object)
+데이터를 저장할 목적으로 예약되어 있습니다.
+</p>
+<h3 id="TypeSpecificNames">유형별 열 이름</h3>
+<p>
+ 특정 유형의 행에 대한 열과의 작업을 돕기 위해, 연락처 제공자는
+ 유형별 열 이름 상수도 제공합니다. 이는
+{@link android.provider.ContactsContract.CommonDataKinds}의 하위 클래스에서 정의합니다. 이 상수는 그저 같은 열 이름에
+서로 다른 상수 이름을 부여할 뿐이며, 이렇게 하면 개발자가 특정 유형의 행에 있는 데이터에
+액세스하기 쉽습니다.
+</p>
+<p>
+ 예를 들어, {@link android.provider.ContactsContract.CommonDataKinds.Email} 클래스는
+MIME 유형{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
+Email.CONTENT_ITEM_TYPE}을 갖는
+{@link android.provider.ContactsContract.Data} 행에
+대한 유형별 열 이름 상수를 정의합니다. 이 클래스에는 이메일 주소 열에 대한
+ 상수 {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS}가
+들어있습니다.
+{@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS}의 실제 값은
+"data1"이고, 이는 열의 일반 이름과 같습니다.
+</p>
+<p class="caution">
+ <strong>주의:</strong> 개발자 본인의 사용자 지정 데이터를
+{@link android.provider.ContactsContract.Data} 테이블에
+추가할 때 제공자의 미리 정의된 MIME 유형 중 하나가 있는 행을 사용하면 안 됩니다. 그렇게 하면 데이터가 손실되거나 제공자의 오작동을
+유발할 수 있습니다. 예를 들어, MIME 유형
+ {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
+ Email.CONTENT_ITEM_TYPE} 안에
+<code>DATA1</code> 열에 있는 이메일 주소 대신 사용자 이름이 들어있는 행은 추가하면 안 됩니다. 해당 행에 개발자 나름의 사용자 지정 MIME 유형을 사용하는 경우
+본인만의 유형별 열 이름을 자유자재로 정의하고 이러한 열을 마음대로 사용해도 됩니다.
+</p>
+<p>
+ 그림 2는
+{@link android.provider.ContactsContract.Data} 행에서 설명 열과 데이터 열이 나타나는 방식과 유형별 열 이름이
+일반 열 이름에 "오버레이"되는 방식을 나타낸 것입니다.
+</p>
+<img src="{@docRoot}images/providers/data_columns.png" alt="How type-specific column names map to generic column names" height="311" id="figure2" />
+<p class="img-caption">
+ <strong>그림 2.</strong> 유형별 열 이름과 일반 열 이름입니다.
+</p>
+<h3 id="ColumnMaps">유형별 열 이름 클래스</h3>
+<p>
+ 표 2는 가장 보편적으로 사용되는 유형별 열 이름 클래스를 목록으로 나열한 것입니다.
+</p>
+<p class="table-caption" id="table2">
+ <strong>표 2.</strong> 유형별 열 이름 클래스</p>
+<table>
+ <tr>
+ <th scope="col">매핑 클래스</th>
+ <th scope="col">데이터 유형</th>
+ <th scope="col">참고</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td>
+ <td>이 데이터 행과 연관된 원시 연락처의 이름 데이터입니다.</td>
+ <td>하나의 원시 연락처에는 이러한 행이 딱 하나만 있습니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td>
+ <td>이 데이터 행과 연관된 원시 연락처의 기본 사진입니다.</td>
+ <td>하나의 원시 연락처에는 이러한 행이 딱 하나만 있습니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td>
+ <td>이 데이터 행과 연관된 원시 연락처의 이메일 주소입니다.</td>
+ <td>하나의 원시 연락처에는 여러 개의 이메일 주소가 있을 수 있습니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td>
+ <td>이 데이터 행과 연관된 원시 연락처의 우편 주소입니다.</td>
+ <td>하나의 원시 연락처에는 여러 개의 우편 주소가 있을 수 있습니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td>
+ <td>원시 연락처를 연락처 제공자의 그룹 중 하나와 연결하는 식별자입니다.</td>
+ <td>
+ 그룹은 계정 유형과 계정 이름의 선택적 기능입니다. 이러한 내용은
+<a href="#Groups">연락처 그룹</a> 섹션에 자세히 설명되어 있습니다.
+ </td>
+ </tr>
+</table>
+<h3 id="ContactBasics">연락처</h3>
+<p>
+ 연락처 제공자는 모든 계정 유형과 계정 이름을 통틀어 원시 연락처 행을 조합하여
+하나의 <strong>연락처</strong>를 형성합니다. 이렇게 하면 사용자가 한 사람에 대해 수집한
+모든 데이터를 표시하고 수정하기 쉽습니다. 연락처 제공자는 새 연락처 행의 생성을 관리하고
+원시 연락처를 기존 연락처 행과 통합하기도 합니다. 애플리케이션과
+동기화 어댑터는 모두 연락처를 추가할 수 없으며, 연락처 행에 있는 열 중 몇몇은 읽기 전용입니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 연락처 제공자에 연락처를 추가하려고
+{@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}를 사용하는 경우,
+{@link java.lang.UnsupportedOperationException} 예외가 발생합니다. "읽기 전용"으로 표시된 열을 업데이트하려고 하면
+그 업데이트는 무시됩니다.
+</p>
+<p>
+ 연락처 제공자는 기존 연락처 어느 것과도 일치하지 않는 새로운 원시 연락처가 추가되면
+새로운 연락처를 생성합니다. 제공자가 이 작업을 하는 또 다른 경우는
+기존 원시 연락처의 데이터가 변경되어 이전에 첨부되어 있던 연락처에 더 이상 일치하지 않는
+경우입니다. 애플리케이션이나 동기화 어댑터가
+기존 연락처와 <em>일치하는</em> 새로운 원시 연락처를 생성하면, 새로운 원시 연락처는
+기존 연락처에 통합됩니다.
+</p>
+<p>
+ 연락처 제공자는
+{@link android.provider.ContactsContract.Contacts Contacts} 테이블에 있는 연락처 행의 <code>_ID</code> 열로
+연락처 행과 원시 연락처 행를 연결합니다. 원시 연락처 테이블 {@link android.provider.ContactsContract.RawContacts}의 <code>CONTACT_ID</code> 행에는
+각 원시 연락처 행과 관련된 연락처 행에 대한 <code>_ID</code> 값이
+들어있습니다.
+</p>
+<p>
+ {@link android.provider.ContactsContract.Contacts} 테이블에는 연락처 행에 대한 "영구" 링크인
+{@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} 열도
+있습니다. 연락처 제공자가 연락처를 자동으로 관리하므로,
+통합이나 동기화에 응답하여 연락처 행의 {@code android.provider.BaseColumns#_ID} 값을
+변경할 수도 있습니다. 이런 일이 발생한다 하더라도 콘텐츠 URI
+{@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}와
+연락처의 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}는 여전히
+연락처 행을 가리키므로,
+{@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}를
+사용하여 "즐겨찾기" 연락처에 대한 연결 등을 그대로 유지할 수 있습니다. 이 열에는
+{@code android.provider.BaseColumns#_ID} 열의 형식과 관련이 없는 나름의 형식이 있습니다.
+</p>
+<p>
+ 그림 3은 세 가지 기본 테이블이 서로 관련되는 방식을 나타낸 것입니다.
+</p>
+<img src="{@docRoot}images/providers/contacts_tables.png" alt="Contacts provider main tables" height="514" id="figure4" />
+<p class="img-caption">
+ <strong>그림 3.</strong> 연락처, 원시 연락처 및 세부 사항 테이블의 관계입니다.
+</p>
+<h2 id="Sources">동기화 어댑터의 데이터</h2>
+<p>
+ 사용자가 연락처 데이터를 기기에 직접 입력하기도 하지만, 데이터는 웹 서비스에서
+<strong>동기화 어댑터</strong>를 통해 연락처 제공자로 흘러들어가기도 합니다. 이것이 기기와
+서비스 사이에서 데이터의 전송을 자동화하는 것입니다. 동기화 어댑터는 시스템의 제어를 받으며
+배경에서 실행되고, {@link android.content.ContentResolver} 메서드를
+호출하여 데이터를 관리합니다.
+</p>
+<p>
+ Android에서 동기화 어댑터와 함께 작업하는 웹 서비스는 계정 유형으로 식별됩니다.
+ 각 동기화 어댑터는 계정 유형 하나에 통하지만, 그 유형에 대한 여러 개의 계정이름을
+지원할 수 있습니다. 계정 유형과 계정 이름은
+<a href="#RawContactsExample">원시 연락처 데이터 소스</a> 섹션에 간단히 설명되어 있습니다. 다음 정의는 좀 더 자세한 내용을 제공하며,
+계정 유형과 이름이 동기화 어댑터와 서비스에 관련되는 방식을 설명합니다.
+</p>
+<dl>
+ <dt>
+ 계정 유형
+ </dt>
+ <dd>
+ 사용자가 데이터를 저장해둔 서비스를 식별합니다. 대부분의 경우, 사용자가
+서비스로 인증해야 합니다. 예를 들어, Google 주소록은 계정 유형이고, 이는
+코드 <code>google.com</code>으로 식별됩니다. 이 값은
+{@link android.accounts.AccountManager}가 사용하는 계정 유형에 상응합니다.
+ </dd>
+ <dt>
+ 계정 이름
+ </dt>
+ <dd>
+ 하나의 계정 유형에 대한 특정 계정 또는 로그인을 식별합니다. Google 주소록 계정은
+Google 계정과 같고, 이는 계정 이름으로 이메일 주소를 사용합니다.
+ 다른 서비스는 한 단어로 된 사용자 이름이나 숫자 ID를 사용할 수 있습니다.
+ </dd>
+</dl>
+<p>
+ 계정 유형은 고유하지 않아도 됩니다. 한 사람의 사용자가 여러 개의 Google 주소록을 구성할 수 있고
+그 데이터를 연락처 제공자에 다운로드할 수 있습니다. 이런 일은 사용자에게
+개인용 계정 이름에 대한 개인용 연락처가 한 세트 있고, 업무용으로 또 한 세트가 있는 경우 일어납니다. 계정 이름은 보통
+고유합니다. 이 둘은 함께 사용되어 연락처 제공자와 외부 서비스 사이의 특정 데이터
+흐름을 식별합니다.
+</p>
+<p>
+ 서비스의 데이터를 연락처 제공자에 전송하려면, 나름의
+동기화 어댑터를 작성해야 합니다. 이 내용은
+<a href="#SyncAdapters">연락처 제공자 동기화 어댑터</a> 섹션에 자세히 설명되어 있습니다.
+</p>
+<p>
+ 그림 4는 연락처 제공자가 사람에 대한 데이터 흐름에
+어떻게 들어맞는지 나타낸 것입니다. "동기화 어댑터"라고 표시된 상자에서, 각 어댑터에는 계정 유형에 따라 레이블이 붙어 있습니다.
+</p>
+<img src="{@docRoot}images/providers/ContactsDataFlow.png" alt="Flow of data about people" height="252" id="figure5" />
+<p class="img-caption">
+ <strong>그림 4.</strong> 연락처 제공자의 데이터 흐름입니다.
+</p>
+<h2 id="Permissions">필수 권한</h2>
+<p>
+ 연락처 제공자에 액세스하고자 하는 애플리케이션은 다음 권한을
+요청해야 합니다.
+</p>
+<dl>
+ <dt>하나 이상의 테이블에 대한 읽기 액세스</dt>
+ <dd>
+ {@link android.Manifest.permission#READ_CONTACTS},
+<code>AndroidManifest.xml</code>에서
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> 요소와 함께
+<code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</code>로 지정된 것.
+ </dd>
+ <dt>하나 이상의 테이블에 대한 쓰기 액세스</dt>
+ <dd>
+ {@link android.Manifest.permission#WRITE_CONTACTS},
+<code>AndroidManifest.xml</code>에서
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> 요소와 함께
+<code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</code>로 지정된 것.
+ </dd>
+</dl>
+<p>
+ 이들 권한은 사용자 프로필 데이터로 확대되지 않습니다. 사용자 프로필과
+필수 권한은
+다음 섹션인 <a href="#UserProfile">사용자 프로필</a>에서 논의합니다.
+</p>
+<p>
+ 사용자의 연락처 데이터는 중요한 개인 정보라는 사실을 명심하십시오. 사용자는 자신의
+개인정보보호를 중요하게 생각하고 신경 쓰기 때문에 애플리케이션이 자신이나 자신의 연락처에 관한 정보를 수집하는 것을 바라지 않습니다.
+ 사용자의 연락처 데이터에 액세스할 권한이 필요한 이유가 분명하지 않으면 여러분의
+애플리케이션에 낮은 순위를 매기거나 설치를 거부할 수도 있습니다.
+</p>
+<h2 id="UserProfile">사용자 프로필</h2>
+<p>
+ {@link android.provider.ContactsContract.Contacts} 테이블에 있는 한 개의 행에는 기기의 사용자에 대한 프로필
+데이터가 담겨 있습니다. 이 데이터는 사용자의 연락처 중 하나라기보다는 기기의 <code>user</code>를
+설명하는 것입니다. 프로필 연락처 행은
+프로필을 사용하는 각 시스템에 대한 원시 연락처 행에 연결되어 있습니다.
+ 각 프로필 원시 연락처 행에는 여러 개의 데이터 행이 있을 수 있습니다. 사용자 프로필에 액세스하기 위한 상수는
+{@link android.provider.ContactsContract.Profile} 클래스에서 이용할 수 있습니다.
+</p>
+<p>
+ 사용자 프로필에 액세스하려면 특수 권한이 필요합니다. 읽기와 쓰기에 필요한
+{@link android.Manifest.permission#READ_CONTACTS}와
+{@link android.Manifest.permission#WRITE_CONTACTS} 권한 외에도,
+사용자 프로필에 액세스하려면 각각 읽기와 쓰기 액세스를 위한{@code android.Manifest.permission#READ_PROFILE}과
+{@code android.Manifest.permission#WRITE_PROFILE} 권한이
+필요합니다.
+</p>
+<p>
+ 사용자의 프로필은 중요한 정보로 간주해야 한다는 점을 명심하십시오.
+{@code android.Manifest.permission#READ_PROFILE}권한을 사용하면 개발자가 기기 사용자의
+개인 식별 데이터에 액세스할 수 있게 해줍니다. 애플리케이션 설명에서
+사용자에게 왜 여러분이 사용자 프로필 권한을 필요로 하는지 밝혀두어야 합니다.
+</p>
+<p>
+ 사용자 프로필이 포함된 연락처 행을 검색하려면,
+{@link android.content.ContentResolver#query(Uri,String[], String, String[], String)
+ContentResolver.query()}를 호출합니다. 콘텐츠 URI 를
+{@link android.provider.ContactsContract.Profile#CONTENT_URI}로 설정하고
+선택 기준은 아무것도 제공하지 마십시오. 이 콘텐츠 URI는 원시 연락처 또는 프로필에 대한 데이터를 검색하기 위한
+기본 URI로도 쓸 수 있습니다. 예를 들어, 이 코드 조각은 프로필에 대한 데이터를 검색합니다.
+</p>
+<pre>
+// Sets the columns to retrieve for the user profile
+mProjection = new String[]
+ {
+ Profile._ID,
+ Profile.DISPLAY_NAME_PRIMARY,
+ Profile.LOOKUP_KEY,
+ Profile.PHOTO_THUMBNAIL_URI
+ };
+
+// Retrieves the profile from the Contacts Provider
+mProfileCursor =
+ getContentResolver().query(
+ Profile.CONTENT_URI,
+ mProjection ,
+ null,
+ null,
+ null);
+</pre>
+<p class="note">
+ <strong>참고:</strong> 여러 개의 연락처 행을 검색하고 그 중 하나가
+사용자 프로필인지 판별하고자 하는 경우,
+행의 {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} 열을 테스트합니다. 이 열은
+해당 연락처가 사용자 프로필이면 "1"로 설정됩니다.
+</p>
+<h2 id="ContactsProviderMetadata">연락처 제공자 메타데이터</h2>
+<p>
+ 연락처 제공자는 리포지토리에서 연락처 데이터 상태를
+추적하는 데이터를 관리합니다. 이 리포지토리 관련 데이터는
+원시 연락처, 데이터 및 연락처 테이블 행,
+{@link android.provider.ContactsContract.Settings} 테이블 및
+{@link android.provider.ContactsContract.SyncState} 테이블 등의 여러 장소에 저장됩니다. 다음 표는 각 메타데이터 조각이 미치는
+영향을 나타낸 것입니다.
+</p>
+<p class="table-caption" id="table3">
+ <strong>표 3.</strong> 연락처 제공자의 메타데이터</p>
+<table>
+ <tr>
+ <th scope="col">테이블</th>
+ <th scope="col">열</th>
+ <th scope="col">값</th>
+ <th scope="col">의미</th>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.RawContacts}</td>
+ <td rowspan="2">{@link android.provider.ContactsContract.SyncColumns#DIRTY}</td>
+ <td>"0" - 마지막 동기화 이후로 변경되지 않았습니다.</td>
+ <td rowspan="2">
+ 기기에서 변경되었고 서버로 다시 동기화되어야 하는 원시 데이터를
+표시합니다. 이 값은 Android 애플리케이션이 행을 업데이트하면 연락처 제공자가
+자동으로 설정합니다.
+ <p>
+ 원시 연락처나 데이터 테이블을 수정하는 동기화 어댑터는
+언제나 문자열 {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER}를
+자신이 사용하는 콘텐츠 URI에 추가해야 합니다. 이렇게 하면 제공자가 행을 변경(dirty)으로 표시하지 못하게 방지합니다.
+ 그렇지 않으면, 동기화 어댑터 수정이 로컬 수정으로 나타나며
+서버가 수정의 근원이었다 하더라도 이 내용이 다시 서버로 전송됩니다.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>"1" - 마지막 동기화 이후 변경되었고, 서버에 다시 동기화해야 합니다.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.RawContacts}</td>
+ <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td>
+ <td>이 행의 버전 번호입니다.</td>
+ <td>
+ 연락처 제공자는 행이나 관련 데이터가 변경될 때마다 이 값을 자동으로
+증가시킵니다.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.Data}</td>
+ <td>{@link android.provider.ContactsContract.DataColumns#DATA_VERSION}</td>
+ <td>이 행의 버전 번호입니다.</td>
+ <td>
+ 연락처 제공자는 데이터 행이 변경될 때마다 이 값을 자동으로
+증가시킵니다.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.RawContacts}</td>
+ <td>{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}</td>
+ <td>
+ 이 원시 연락처를 자신이 생성된 계정에 대해 고유하게 식별하는
+문자열 값입니다.
+ </td>
+ <td>
+ 동기화 어댑터가 새로운 원시 연락처를 생성하면, 이 열이
+해당 원시 연락처에 대한 서버의 고유 ID로 설정되어야 합니다. Android 애플리케이션이 새로운 원시 연락처를 생성하면,
+애플리케이션은 이 열을 빈 채로 두어야 합니다. 이것은 동기화 어댑터에
+서버에 새 원시 데이터를 생성해야 한다고 신호하고,
+{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}에 대한 값을 가져오라고 알립니다.
+ <p>
+ 특히, 소스 ID는 각 계정 유형에 대해 <strong>고유</strong>해야 하고
+동기화 전체에서 안정적이어야 합니다.
+ </p>
+ <ul>
+ <li>
+ 고유: 하나의 계정에 대한 각 원시 연락처에는 나름의 소스 ID가 있어야 합니다. 개발자가
+이것을 강제 적용하지 않으면 연락처 애플리케이션에 문제를 유발하게 됩니다.
+ 같은 계정 <em>유형</em>에 대한 두 개의 원시 연락처는 소스 ID가
+같을 수 있다는 점을 유의하십시오. 예를 들어,
+{@code emily.dickinson@gmail.com} 계정에 대한 원시 연락처 "Thomas Higginson"은
+{@code emilyd@gmail.com} 계정에 대한
+원시 연락처 "Thomas Higginson"과 소스 ID가 같을 수 있습니다.
+ </li>
+ <li>
+ 안정적: 소스 ID는 원시 연락처에 대한 온라인 서비스의 데이터 중 영구적인
+부분입니다. 예를 들어, 사용자가 앱 설정에서 연락처 저장소를 삭제하고 다시 동기화하면
+복원된 원시 연락처의 소스 ID는 전과 같아야
+합니다. 개발자가 이것을 강제 적용하지 않으면 바로 가기가 더 이상
+ 작동하지 않습니다.
+ </li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.Groups}</td>
+ <td rowspan="2">{@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE}</td>
+ <td>"0" - 이 그룹의 연락처는 Android 애플리케이션 UI에 표시되지 않아야 합니다.</td>
+ <td>
+ 이 열은 사용자가 특정 그룹에 연락처를 숨길 수 있게 해주는 서버와의
+호환성을 위한 것입니다.
+ </td>
+ </tr>
+ <tr>
+ <td>"1" - 이 그룹의 연락처는 애플리케이션 UI에 표시되어도 됩니다.</td>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.Settings}</td>
+ <td rowspan="2">
+ {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE}</td>
+ <td>
+ "0" - 이 계정과 계정 유형의 경우, 그룹에 속하지 않는 연락처는 Android 애플리케이션 UI에
+표시되지 않습니다.
+ </td>
+ <td rowspan="2">
+ 기본적으로, 연락처에 그룹에 속한 원시 데이터가 하나도 없는 경우 이는 표시되지 않습니다(원시 연락처의 그룹 구성원은
+{@link android.provider.ContactsContract.Data} 테이블에서
+하나 이상의 {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} 행으로
+표시됩니다).
+ 계정 유형과 계정에 대한 {@link android.provider.ContactsContract.Settings} 테이블 행에서
+이 플래그를 설정하면 그룹이 없는 연락처가 표시되도록 강제할 수 있습니다.
+ 이 플래그의 용도 중 하나는 그룹을 사용하지 않는 서버로부터 가져온 연락처를 표시하는 것입니다.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ "1" - 이 계정과 계정 유형의 경우, 그룹에 속하지 않는 연락처가 애플리케이션 UI에
+표시됩니다.
+ </td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.SyncState}</td>
+ <td>(모두)</td>
+ <td>
+ 이 테이블을 사용하여 동기화 어댑터의 메타데이터를 저장합니다.
+ </td>
+ <td>
+ 이 테이블을 사용하면 동기화 상태와 기타 동기화 관련 데이터를 기기에 영구적으로
+저장할 수 있습니다.
+ </td>
+ </tr>
+</table>
+<h2 id="Access">연락처 제공자 액세스</h2>
+<p>
+ 이 섹션은 연락처 제공자에서 가져온 데이터에 액세스하는 법에 대한 지침을 제공하며,
+요점은 다음과 같습니다.
+</p>
+<ul>
+ <li>
+ 엔티티 쿼리.
+ </li>
+ <li>
+ 일괄 수정.
+ </li>
+ <li>
+ 인텐트로 검색 및 수정.
+ </li>
+ <li>
+ 데이터 무결성.
+ </li>
+</ul>
+<p>
+ 동기화 어댑터에서 수정하는 방법은
+<a href="#SyncAdapters">연락처 제공자 동기화 어댑터</a> 섹션에도 자세히 설명되어 있습니다.
+</p>
+<h3 id="Entities">엔티티 쿼리</h3>
+<p>
+ 연락처 제공자 테이블은 계층을 사용하여 조직화되어 있으므로,
+행과 그 행에 연결된 모든 "하위" 행을 검색하는 것이 유용할 때가 많습니다. 예를 들어,
+어떤 개인의 모든 정보를 표시하려면
+하나의 {@link android.provider.ContactsContract.Contacts} 행에 대한 모든
+{@link android.provider.ContactsContract.RawContacts} 행을 검색하거나 하나의
+{@link android.provider.ContactsContract.RawContacts} 행에 대한 모든
+{@link android.provider.ContactsContract.CommonDataKinds.Email} 행을 검색하는 것이 좋습니다. 이를 용이하게 하기 위해,
+연락처 제공자는 테이블 사이를 연결하는 데이터베이스 역할을 하는 <strong>엔티티</strong> 구조를
+제공합니다.
+</p>
+<p>
+ 하나의 엔티티는 마치 상위 테이블과 그 하위 테이블에서 가져온 선택된 몇 개의 열로 이루어진 테이블과 같습니다.
+ 엔티티를 쿼리하는 경우, 해당 엔티티에서 사용할 수 있는 열을 기반으로 하여 예측과 검색
+기준을 제공합니다. 그 결과도 도출되는 것이 {@link android.database.Cursor}이며,
+여기에 검색된 각 하위 테이블에 대해 행이 하나씩 들어있습니다. 예를 들어 연락처 이름에 대해
+{@link android.provider.ContactsContract.Contacts.Entity}를 쿼리하고
+그 이름에 대한 모든 원시 연락처에 대한 모든 {@link android.provider.ContactsContract.CommonDataKinds.Email} 행을 쿼리하면
+{@link android.database.Cursor}를 돌려받게 되며 이 안에
+각 {@link android.provider.ContactsContract.CommonDataKinds.Email}행에 대한 행이 하나씩 들어있습니다.
+</p>
+<p>
+ 엔티티는 쿼리를 단순화합니다. 엔티티를 사용하면 연락처나 원시 연락처에 대한 모든 연락처 데이터를
+한꺼번에 검색할 수 있습니다. 즉 우선 상위 테이블을 검색하여 ID를 가져오고, 그런 다음
+하위 테이블을 그 ID로 검색하지 않아도 된다는 뜻입니다. 또한, 연락처 제공자에는 엔티티에 대한 쿼리를
+하나의 트랜잭션으로 처리하므로, 검색된 데이터가 내부적으로 일관성을 유지하도록
+보장합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 하나의 엔티티에 상위 및 하위 테이블의 모든 열이 들어있지는 않은 것이
+보통입니다. 엔티티에 대한 열 이름 상수 목록에 없는 열 이름으로 작업하려 시도하면,
+{@link java.lang.Exception}이 발생합니다.
+</p>
+<p>
+ 다음 조각은 하나의 연락처에 대해 모든 원시 연락처 행을 검색하는 방법을 나타낸 것입니다. 이 조각은
+두 개의 액티비티, 즉 "기본"과 "세부"를 가진 더 큰 애플리케이션의 일부입니다. 기본 액티비티는
+연락처 행 목록을 보여줍니다. 사용자가 하나를 선택하면, 이 액티비티가 해당 목록의 ID를
+세부 액티비티에 전송합니다. 세부 액티비티는 {@link android.provider.ContactsContract.Contacts.Entity}를 사용하여
+선택된 연락처와 연관된 모든 원시 연락처에서
+모든 데이터 행을 표시합니다.
+</p>
+<p>
+ 이 조각은 "세부" 액티비티에서 가져온 것입니다.
+</p>
+<pre>
+...
+ /*
+ * Appends the entity path to the URI. In the case of the Contacts Provider, the
+ * expected URI is content://com.google.contacts/#/entity (# is the ID value).
+ */
+ mContactUri = Uri.withAppendedPath(
+ mContactUri,
+ ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
+
+ // Initializes the loader identified by LOADER_ID.
+ getLoaderManager().initLoader(
+ LOADER_ID, // The identifier of the loader to initialize
+ null, // Arguments for the loader (in this case, none)
+ this); // The context of the activity
+
+ // Creates a new cursor adapter to attach to the list view
+ mCursorAdapter = new SimpleCursorAdapter(
+ this, // the context of the activity
+ R.layout.detail_list_item, // the view item containing the detail widgets
+ mCursor, // the backing cursor
+ mFromColumns, // the columns in the cursor that provide the data
+ mToViews, // the views in the view item that display the data
+ 0); // flags
+
+ // Sets the ListView's backing adapter.
+ mRawContactList.setAdapter(mCursorAdapter);
+...
+&#64;Override
+public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+
+ /*
+ * Sets the columns to retrieve.
+ * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
+ * DATA1 contains the first column in the data row (usually the most important one).
+ * MIMETYPE indicates the type of data in the data row.
+ */
+ String[] projection =
+ {
+ ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
+ ContactsContract.Contacts.Entity.DATA1,
+ ContactsContract.Contacts.Entity.MIMETYPE
+ };
+
+ /*
+ * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
+ * contact collated together.
+ */
+ String sortOrder =
+ ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
+ " ASC";
+
+ /*
+ * Returns a new CursorLoader. The arguments are similar to
+ * ContentResolver.query(), except for the Context argument, which supplies the location of
+ * the ContentResolver to use.
+ */
+ return new CursorLoader(
+ getApplicationContext(), // The activity's context
+ mContactUri, // The entity content URI for a single contact
+ projection, // The columns to retrieve
+ null, // Retrieve all the raw contacts and their data rows.
+ null, //
+ sortOrder); // Sort by the raw contact ID.
+}
+</pre>
+<p>
+ 로딩이 완료되면, {@link android.app.LoaderManager}가
+{@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D)
+onLoadFinished()}에 대한 콜백을 호출합니다. 이 메서드로 수신되는 인수 중 하나가
+{@link android.database.Cursor}로, 여기에 쿼리 결과도 함께 들어옵니다. 개발자 본인의 앱에서는, 이
+{@link android.database.Cursor}에서 데이터를 가져와 이를 표시할 수도 있고 여기에 작업을 더할 수도 있습니다.
+</p>
+<h3 id="Transactions">일괄 수정</h3>
+<p>
+ 연락처 제공자에서 데이터를 삽입, 업데이트 및 삭제하는 경우 가급적이면
+"일괄 모드"를 쓰는 것이 좋습니다. 이때
+{@link android.content.ContentProviderOperation} 객체의 {@link java.util.ArrayList}를 생성하고
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}를 호출하면 됩니다. 연락처 제공자는
+
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}에서의 모든 작업을
+하나의 트랜잭션으로 수행하기 때문에, 수정한 내용이 일관되지 않은 상태로 연락처 리포지토리를
+떠날 일이 결코 없습니다. 일괄 수정을 사용하면 원시 연락처와 그 세부 데이터를 동시에 삽입하는 것도
+쉽습니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> <em>하나의</em> 원시 연락처를 수정하려면 수정 작업을 앱에서 처리하는 것보다는
+인텐트를 기기의 연락처 애플리케이션에 보내는 방안을 고려하십시오.
+이렇게 하는 방법이
+<a href="#Intents">인텐트로 검색 및 수정</a> 섹션에 자세히 설명되어 있습니다.
+</p>
+<h4>양보 지점</h4>
+<p>
+ 대량의 작업이 들어있는 일괄 수정은 다른 프로세스를 차단하므로,
+그 결과 전반적으로 불량한 사용자 환경을 유발할 수 있습니다. 수행하고자 하는 모든 수정 작업을 가능한 한
+적은 수의 별도의 목록으로 정리하고 그와 동시에 이 작업이 시스템을 차단하지 못하도록 방지하려면
+하나 이상의 작업에 <strong>양보 지점</strong>을 설정해야 합니다.
+ 양보 지점은 {@link android.content.ContentProviderOperation#isYieldAllowed()} 값이 <code>true</code>로 설정된 {@link android.content.ContentProviderOperation} 객체입니다.
+
+ 연락처 제공자가 양보 지점을 만나면
+다른 프로세스가 실행되도록 작업을 잠시 멈추고 현재 트랜잭션을 종료합니다. 제공자가 다시 시작되면, 이는
+{@link java.util.ArrayList}에서 다음 작업을 계속 진행하고
+새 트랜잭션을 시작합니다.
+</p>
+<p>
+ 양보 지점을 사용하면 그 결과
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}로의 호출 한 건당 하나 이상의 트랜잭션이 생기는 것은 사실입니다. 이 때문에,
+ 양보 지점은 관련된 행 한 세트에서 마지막 작업에 설정해야 합니다.
+ 예를 들어, 원시 연락처 행과 관련된 데이터 행을 추가하는 세트의 마지막 작업에
+양보 지점을 설정하거나, 하나의 연락처와 관련된 행 한 세트의
+마지막 작업에 양보 지점을 설정해야 합니다.
+</p>
+<p>
+ 양보 지점은 원자성 작업의 단위이기도 합니다. 두 개의 양보 지점 사이를 향한 액세스는 모두
+한 가지 단위로서 성공 또는 실패합니다. 양보 지점을 설정하지 않는 경우, 가장 작은
+원자성 작업은 작업 전체가 됩니다. 양보 지점을 사용하면, 작업이
+시스템 성능을 저하하지 않도록 방지하는 동시에 작업의 하위 세트가 원자성 작업이도록
+보장할 수 있습니다.
+</p>
+<h4>수정 역참조</h4>
+<p>
+ 새로운 원시 연락처 행과 관련 데이터 행을
+일련의 {@link android.content.ContentProviderOperation} 개체로 삽입할 때는,
+ 원시 연락처의
+{@code android.provider.BaseColumns#_ID} 값을
+{@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID} 값으로 삽입하여 데이터 행과 원시 연락처 행을 연결해야 합니다. 그러나, 이 값은
+데이터 행에 대하여 {@link android.content.ContentProviderOperation}을
+생성하는 경우에는 사용할 수 없습니다. 원시 연락처 행에 대해 {@link android.content.ContentProviderOperation}
+을 아직 적용하지 않았기 때문입니다. 이 문제를 해결하려면
+{@link android.content.ContentProviderOperation.Builder} 클래스에
+{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()} 메서드가 있어야 합니다.
+ 이 메서드를 사용하면 열을 이전 작업의 결과로 삽입 또는 수정할 수
+있습니다.
+</p>
+<p>
+ {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
+메서드에는 인수가 두 가지 있습니다.
+</p>
+ <dl>
+ <dt>
+ <code>key</code>
+ </dt>
+ <dd>
+ 키-값 쌍의 키입니다. 이 인수의 값은 수정하는 테이블의
+열 이름이어야 합니다.
+ </dd>
+ <dt>
+ <code>previousResult</code>
+ </dt>
+ <dd>
+
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}의 {@link android.content.ContentProviderResult} 객체 배열에 있는
+값의 0 기반 색인입니다.
+일괄 작업이 적용되면 각 작업의 결과가
+결과의 중간 배열에 저장됩니다. <code>previousResult</code> 값은
+이러한 결과 중 하나의 색인이고, 이는 <code>key</code> 값으로
+검색 및 저장됩니다. 이것을 사용하면 새 원시 연락처 레코드를 삽입하고
+{@code android.provider.BaseColumns#_ID} 값을 다시 가져온 뒤,
+{@link android.provider.ContactsContract.Data} 행을 추가할 때 해당 값을 "역참조"할 수 있게 해줍니다.
+ <p>
+
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}를 처음 호출할 때,
+개발자가 제공하는 {@link android.content.ContentProviderOperation} 객체의 {@link java.util.ArrayList} 크기와 같은 크기로
+전체 결과 배열이 생성됩니다. 그러나
+결과 배열의 모든 요소는 <code>null</code>로 설정되고,
+아직 적용되지 않은 작업 결과에 대한 역참조를 수행하려 시도하면
+{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}가
+{@link java.lang.Exception}을 발생시킵니다.
+
+ </p>
+ </dd>
+ </dl>
+<p>
+ 다음 조각은 새로운 원시 연락처와 데이터를 일괄 삽입하는 방법을 나타낸 것입니다. 여기에는
+양보 지점을 지정하고 역참조를 사용하는 코드가 포함되어 있습니다. 이 조각은
+<code>createContacEntry()</code> 메서드의 확장 버전이며, 이는
+<code><a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Contact Manager</a></code> 샘플 애플리케이션에 있는 <code>ContactAdder</code> 클래스의
+일부입니다.
+</p>
+<p>
+ 첫 번째 조각은 UI에서 연락처 데이터를 검색합니다. 이 시점에서 사용자는 이미
+새로운 원시 연락처를 추가할 계정을 선택하였습니다.
+</p>
+<pre>
+// Creates a contact entry from the current UI values, using the currently-selected account.
+protected void createContactEntry() {
+ /*
+ * Gets values from the UI
+ */
+ String name = mContactNameEditText.getText().toString();
+ String phone = mContactPhoneEditText.getText().toString();
+ String email = mContactEmailEditText.getText().toString();
+
+ int phoneType = mContactPhoneTypes.get(
+ mContactPhoneTypeSpinner.getSelectedItemPosition());
+
+ int emailType = mContactEmailTypes.get(
+ mContactEmailTypeSpinner.getSelectedItemPosition());
+</pre>
+<p>
+ 다음 조각은
+{@link android.provider.ContactsContract.RawContacts} 테이블에 원시 연락처 행을 삽입하는 작업을 생성합니다.
+</p>
+<pre>
+ /*
+ * Prepares the batch operation for inserting a new raw contact and its data. Even if
+ * the Contacts Provider does not have any data for this person, you can't add a Contact,
+ * only a raw contact. The Contacts Provider will then add a Contact automatically.
+ */
+
+ // Creates a new array of ContentProviderOperation objects.
+ ArrayList&lt;ContentProviderOperation&gt; ops =
+ new ArrayList&lt;ContentProviderOperation&gt;();
+
+ /*
+ * Creates a new raw contact with its account type (server type) and account name
+ * (user's account). Remember that the display name is not stored in this row, but in a
+ * StructuredName data row. No other data is required.
+ */
+ ContentProviderOperation.Builder op =
+ ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
+ .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
+ .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+</pre>
+<p>
+ 그런 다음, 코드가 표시 이름, 전화 및 이메일 행에 대한 데이터 행을 생성합니다.
+</p>
+<p>
+ 각 작업 빌더 개체는
+{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}를
+사용하여
+{@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}를 가져옵니다. 참조는
+첫 번째 작업의 {@link android.content.ContentProviderResult} 객체를 다시 가리키고,
+이것이 원시 연락처 행을 추가한 뒤 이의 새 {@code android.provider.BaseColumns#_ID}
+값을 반환합니다. 그 결과, 각 데이터 행은 자동으로 자신의
+{@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}
+에 의해 자신이 속하는 새 {@link android.provider.ContactsContract.RawContacts} 행에 연결됩니다.
+</p>
+<p>
+ 이메일 행을 추가하는 {@link android.content.ContentProviderOperation.Builder} 객체는
+양보 지점을 설정하는 {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean)
+withYieldAllowed()}로 플래그 표시합니다.
+</p>
+<pre>
+ // Creates the display name for the new raw contact, as a StructuredName data row.
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * withValueBackReference sets the value of the first argument to the value of
+ * the ContentProviderResult indexed by the second argument. In this particular
+ * call, the raw contact ID column of the StructuredName data row is set to the
+ * value of the result returned by the first operation, which is the one that
+ * actually adds the raw contact row.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to StructuredName
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+
+ // Sets the data row's display name to the name in the UI.
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+
+ // Inserts the specified phone number and type as a Phone data row
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * Sets the value of the raw contact id column to the new raw contact ID returned
+ * by the first operation in the batch.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to Phone
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
+
+ // Sets the phone number and type
+ .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
+ .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+
+ // Inserts the specified email and type as a Phone data row
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * Sets the value of the raw contact id column to the new raw contact ID returned
+ * by the first operation in the batch.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to Email
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
+
+ // Sets the email address and type
+ .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
+ .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);
+
+ /*
+ * Demonstrates a yield point. At the end of this insert, the batch operation's thread
+ * will yield priority to other threads. Use after every set of operations that affect a
+ * single contact, to avoid degrading performance.
+ */
+ op.withYieldAllowed(true);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+</pre>
+<p>
+ 마지막 조각은 새로운 원시 연락처와 데이터 행을 삽입하는
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}에 대한 호출을
+나타낸 것입니다.
+</p>
+<pre>
+ // Ask the Contacts Provider to create a new contact
+ Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" +
+ mSelectedAccount.getType() + ")");
+ Log.d(TAG,"Creating contact: " + name);
+
+ /*
+ * Applies the array of ContentProviderOperation objects in batch. The results are
+ * discarded.
+ */
+ try {
+
+ getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e) {
+
+ // Display a warning
+ Context ctx = getApplicationContext();
+
+ CharSequence txt = getString(R.string.contactCreationFailure);
+ int duration = Toast.LENGTH_SHORT;
+ Toast toast = Toast.makeText(ctx, txt, duration);
+ toast.show();
+
+ // Log exception
+ Log.e(TAG, "Exception encountered while inserting contact: " + e);
+ }
+}
+</pre>
+<p>
+ 일괄 작업을 사용하면 <strong>낙관적 동시성 제어</strong>도 구현할 수 있습니다.
+이것은 기본 리포지토리를 잠그지 않고도 수정 트랜잭션을 적용할 수 있는 메서드입니다.
+ 이 메서드를 사용하려면 트랜잭션을 적용하고 동시에 발생한
+다른 수정 사항이 있는지 확인합니다. 부합하지 않는 수정이 발생한 것을 발견하면
+트랜잭션을 롤백하고 다시 시도합니다.
+</p>
+<p>
+ 낙관적 동시성 제어는 한 번에 한 명의 사용자만 존재하고 데이터 리포지토리에 대한 동시 액세스가 드문 모바일 기기에
+유용합니다. 잠금을 사용하지 않으므로
+잠금을 설정하거나 다른 트랜잭션이 잠금을 해제하기를 기다리면서 시간을 낭비하지 않습니다.
+</p>
+<p>
+ 하나의
+{@link android.provider.ContactsContract.RawContacts} 행을 업데이트하면서 동시에 낙관적 동시성 제어를 사용하려면, 다음 단계를 따르십시오.
+</p>
+<ol>
+ <li>
+ 검색하는 다른 데이터와 함께 행 연락처의 {@link android.provider.ContactsContract.SyncColumns#VERSION}을
+검색합니다.
+ </li>
+ <li>
+ 제약을 강제 적용하는 데 적합한
+{@link android.content.ContentProviderOperation.Builder} 객체를 하나 생성하되
+{@link android.content.ContentProviderOperation#newAssertQuery(Uri)} 메서드를 사용합니다. 콘텐츠 URI의 경우,
+{@link android.provider.ContactsContract.RawContacts#CONTENT_URI
+ RawContacts.CONTENT_URI}를 사용하되
+이에 추가된 원시 데이터의 {@code android.provider.BaseColumns#_ID}를 함께 씁니다.
+ </li>
+ <li>
+ {@link android.content.ContentProviderOperation.Builder} 개체의 경우,
+{@link android.content.ContentProviderOperation.Builder#withValue(String, Object)
+withValue()}를 호출하여 방금 검색한 버전 번호와 {@link android.provider.ContactsContract.SyncColumns#VERSION} 열을
+비교합니다.
+ </li>
+ <li>
+ 같은 {@link android.content.ContentProviderOperation.Builder}의 경우,
+{@link android.content.ContentProviderOperation.Builder#withExpectedCount(int)
+withExpectedCount()}를 호출하여 이 어설션이 테스트하는 행이 하나뿐이도록 보장합니다.
+ </li>
+ <li>
+ {@link android.content.ContentProviderOperation.Builder#build()}를 호출하여
+{@link android.content.ContentProviderOperation} 객체를 생성하고, 이 객체를
+{@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}에 전달하는 {@link java.util.ArrayList}의 첫 번째 객체로 추가합니다.
+
+ </li>
+ <li>
+ 일괄 트랜잭션을 적용합니다.
+ </li>
+</ol>
+<p>
+ 행을 읽고 수정하려고 시도하는 사이에 다른 작업이 원시 연락처 행을 업데이트하면,
+"어설션" {@link android.content.ContentProviderOperation}은
+실패하고 전체 일괄 작업이 취소됩니다. 그러면 일괄 작업을 다시 시도하거나
+다른 조치를 취하기로 선택할 수 있습니다.
+</p>
+<p>
+ 다음 조각은 {@link android.content.CursorLoader}를 사용하여 단일 원시 연락처를 쿼리한 후
+"어설션" {@link android.content.ContentProviderOperation}을
+생성하는 방법을 나타낸 것입니다.
+</p>
+<pre>
+/*
+ * The application uses CursorLoader to query the raw contacts table. The system calls this method
+ * when the load is finished.
+ */
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
+
+ // Gets the raw contact's _ID and VERSION values
+ mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
+ mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
+}
+
+...
+
+// Sets up a Uri for the assert operation
+Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
+
+// Creates a builder for the assert operation
+ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
+
+// Adds the assertions to the assert operation: checks the version and count of rows tested
+assertOp.withValue(SyncColumns.VERSION, mVersion);
+assertOp.withExpectedCount(1);
+
+// Creates an ArrayList to hold the ContentProviderOperation objects
+ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
+
+ops.add(assertOp.build());
+
+// You would add the rest of your batch operations to "ops" here
+
+...
+
+// Applies the batch. If the assert fails, an Exception is thrown
+try
+ {
+ ContentProviderResult[] results =
+ getContentResolver().applyBatch(AUTHORITY, ops);
+
+ } catch (OperationApplicationException e) {
+
+ // Actions you want to take if the assert operation fails go here
+ }
+</pre>
+<h3 id="Intents">인텐트로 검색 및 수정</h3>
+<p>
+ 기기 연락처 애플리케이션에 인텐트를 전송하면 연락처 제공자에
+간접적으로 액세스할 수 있습니다. 인텐트는 기기의 연락처 애플리케이션 UI를 시작하고, 여기서 사용자는
+연락처 관련 작업을 할 수 있습니다. 사용자가 이런 액세스 유형을 가지고 할 수 있는 일은 다음과 같습니다.
+ <ul>
+ <li>목록에서 연락처를 선택하고 추가 작업을 위해 앱에 반환시킵니다.</li>
+ <li>기존 연락처의 데이터를 편집합니다.</li>
+ <li>새 원시 데이터를 해당되는 계정 중 아무 곳에나 삽입합니다.</li>
+ <li>연락처 또는 연락처 데이터를 삭제합니다.</li>
+ </ul>
+<p>
+ 사용자가 데이터를 삽입하거나 업데이트하고 있다면, 먼저 데이터를 수집하고
+인텐트의 일부로 전송할 수 있습니다.
+</p>
+<p>
+ 인텐트를 사용하여 기기의 연락처 애플리케이션을 통해 연락처 제공자에 액세스하는 경우
+제공자에 액세스하기 위해 개발자 나름의 UI나 코드를 작성하지 않아도 됩니다. 제공자에 대한 읽기 또는 쓰기 권한도 요청하지 않아도
+됩니다. 기기 연락처 애플리케이션은
+연락처에 대한 읽기 권한을 위임할 수 있고, 다른 애플리케이션을 통해 수정하기 때문에
+쓰기 권한도 필요 없습니다.
+</p>
+<p>
+ 제공자에 액세스하기 위해 인텐트를 전송하는 일반적인 과정은
+"인텐트를 통한 데이터 액세스" 섹션의 <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+콘텐츠 제공자 기본 정보</a> 가이드에 상세히 설명되어 있습니다. 이용 가능한 작업에 대해 사용하는 동작,
+MIME 유형 및 데이터 값은 표 4에 요약되어 있고,
+
+{@link android.content.Intent#putExtra(String, String) putExtra()}와 함께 사용할 수 있는 추가 값은
+{@link android.provider.ContactsContract.Intents.Insert}의 참조 문서에 나열되어 있습니다.
+</p>
+<p class="table-caption" id="table4">
+ <strong>표 4.</strong> 연락처 제공자 인텐트
+</p>
+<table style="width:75%">
+ <tr>
+ <th scope="col" style="width:10%">작업</th>
+ <th scope="col" style="width:5%">동작</th>
+ <th scope="col" style="width:10%">데이터</th>
+ <th scope="col" style="width:10%">MIME 유형</th>
+ <th scope="col" style="width:25%">참고</th>
+ </tr>
+ <tr>
+ <td><strong>목록에서 연락처 선택</strong></td>
+ <td>{@link android.content.Intent#ACTION_PICK}</td>
+ <td>
+ 다음 중 하나로 정해집니다.
+ <ul>
+ <li>
+{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI},
+이는 연락처 목록을 표시합니다.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI},
+이는 원시 연락처에 대한 전화 번호 목록을 표시합니다.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI
+StructuredPostal.CONTENT_URI},
+이는 원시 연락처에 대한 우편 주소 목록을 표시합니다.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI},
+이는 원시 연락처에 대한 이메일 주소 목록을 표시합니다.
+ </li>
+ </ul>
+ </td>
+ <td>
+ 사용하지 않음
+ </td>
+ <td>
+ 개발자가 제공하는 콘텐츠 URI에 따라 원시 연락처 목록이나 원시 연락처에서 가져온
+데이터 목록을 표시합니다.
+ <p>
+
+{@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()} 호출,
+이는 선택한 행의 콘텐츠 URI를 반환합니다. URI의 형태는
+테이블의 콘텐츠 URI에 행의 <code>LOOKUP_ID</code>를 추가한 것입니다.
+ 기기의 연락처 앱은 액티비티 수명 동안 이 콘텐츠 URI에
+읽기 및 쓰기 권한을 위임합니다. 자세한 내용은
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+콘텐츠 제공자 기본 정보</a> 가이드를 참조하십시오.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>새 원시 연락처 삽입</strong></td>
+ <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td>
+ <td>N/A</td>
+ <td>
+ {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE
+RawContacts.CONTENT_TYPE}, 일련의 원시 연락처에 대한 MIME 유형입니다.
+ </td>
+ <td>
+ 기기의 연락처 애플리케이션의 <strong>연락처 추가</strong> 화면을 표시합니다. 개발자가
+인텐트에 추가하는 추가 사항 값이 표시됩니다.
+{@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()}와 함께 전송되는 경우,
+새로 추가된 원시 연락처의 콘텐츠 URI는
+"데이터" 필드의 {@link android.content.Intent} 인수에 있는 액티비티의 {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()}
+콜백 메서드로
+다시 전달됩니다. 값을 가져오려면, {@link android.content.Intent#getData()}를 호출합니다.
+ </td>
+ </tr>
+ <tr>
+ <td><strong>연락처 편집</strong></td>
+ <td>{@link android.content.Intent#ACTION_EDIT}</td>
+ <td>
+ 연락처에 대한
+{@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}입니다. 편집자 액티비티를 사용하면 사용자가 이 연락처와 관련된 데이터를 어느 것이든
+편집할 수 있습니다.
+ </td>
+ <td>
+ {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE
+Contacts.CONTENT_ITEM_TYPE}, 하나의 연락처입니다.</td>
+ <td>
+ 연락처 애플리케이션에 연락처 편집 화면을 표시합니다. 개발자가
+인텐트에 추가하는 추가 사항 값이 표시됩니다. 사용자가 <strong>완료</strong>를 클릭하여 편집 내용을 저장하면,
+액티비티가 전경으로 돌아옵니다.
+ </td>
+ </tr>
+ <tr>
+ <td><strong>데이터를 추가할 수 있는 선택기를 표시합니다.</strong></td>
+ <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td>
+ <td>
+ N/A
+ </td>
+ <td>
+ {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE}
+ </td>
+ <td>
+ 이 인텐트는 항상 연락처 앱의 선택기 화면을 표시합니다. 사용자는
+편집할 연락처를 선택하거나 새 연락처를 추가할 수 있습니다. 사용자의 선택에 따라
+편집 또는 추가 화면이 나타나고 개발자가 인텐트에 전달하는 추가 사항 데이터가
+표시됩니다. 앱이 이메일이나 전화 번호 등의 연락처 데이터를 표시하는 경우,
+이 인텐트를 사용하면 사용자가 기존 연락처에 데이터를 추가할 수
+있습니다.
+ <p class="note">
+ <strong>참고:</strong> 이 인텐트의 추가 사항에서는 이름 값을 전송하지 않아도 됩니다.
+사용자가 항상 기존의 이름을 선택하거나 새 이름을 추가하기 때문입니다. 게다가,
+개발자가 이름을 전송하고 사용자가 편집을 선택하면 연락처 앱은 개발자가 전송한 이름을 표시하면서
+이전 값을 재정의하게 됩니다. 사용자가
+이를 눈치채지 못하고 편집 내용을 저장하면 이전 값은 손실됩니다.
+ </p>
+ </td>
+ </tr>
+</table>
+<p>
+ 기기의 연락처 앱은 개발자가 인텐트로 원시 연락처 또는 그에 속한 모든 데이터를 삭제하도록
+허용하지 않습니다. 대신, 원시 연락처를 삭제하려면
+{@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()}
+또는 {@link android.content.ContentProviderOperation#newDelete(Uri)
+ContentProviderOperation.newDelete()}를 사용합니다.
+</p>
+<p>
+ 다음 조각은 새로운 원시 연락처와
+데이터를 삽입하는 인텐트를 구성, 전송하는 방법을 나타낸 것입니다.
+</p>
+<pre>
+// Gets values from the UI
+String name = mContactNameEditText.getText().toString();
+String phone = mContactPhoneEditText.getText().toString();
+String email = mContactEmailEditText.getText().toString();
+
+String company = mCompanyName.getText().toString();
+String jobtitle = mJobTitle.getText().toString();
+
+// Creates a new intent for sending to the device's contacts application
+Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
+
+// Sets the MIME type to the one expected by the insertion activity
+insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
+
+// Sets the new contact name
+insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
+
+// Sets the new company and job title
+insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
+insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);
+
+/*
+ * Demonstrates adding data rows as an array list associated with the DATA key
+ */
+
+// Defines an array list to contain the ContentValues objects for each row
+ArrayList&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
+
+
+/*
+ * Defines the raw contact row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues rawContactRow = new ContentValues();
+
+// Adds the account type and name to the row
+rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
+rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
+
+// Adds the row to the array
+contactData.add(rawContactRow);
+
+/*
+ * Sets up the phone number data row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues phoneRow = new ContentValues();
+
+// Specifies the MIME type for this data row (all data rows must be marked by their type)
+phoneRow.put(
+ ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
+);
+
+// Adds the phone number and its type to the row
+phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
+
+// Adds the row to the array
+contactData.add(phoneRow);
+
+/*
+ * Sets up the email data row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues emailRow = new ContentValues();
+
+// Specifies the MIME type for this data row (all data rows must be marked by their type)
+emailRow.put(
+ ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
+);
+
+// Adds the email address and its type to the row
+emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
+
+// Adds the row to the array
+contactData.add(emailRow);
+
+/*
+ * Adds the array to the intent's extras. It must be a parcelable object in order to
+ * travel between processes. The device's contacts app expects its key to be
+ * Intents.Insert.DATA
+ */
+insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
+
+// Send out the intent to start the device's contacts app in its add contact activity.
+startActivity(insertIntent);
+</pre>
+<h3 id="DataIntegrity">데이터 무결성</h3>
+<p>
+ 연락처 리포지토리에는 사용자 측에서 올바르고 최신일 것으로 기대하는 중요하고 민감한 데이터가 들어있으므로
+연락처 제공자는 데이터 무결성에 대한 잘 정의된 규칙이 있습니다. 개발자
+여러분에게는 연락처 데이터를 수정할 때 이와 같은 규칙을 준수할 의무가 있습니다. 아래에는 중요한 규칙을
+몇 가지 나열해 놓았습니다.
+</p>
+<dl>
+ <dt>
+ {@link android.provider.ContactsContract.RawContacts} 행을 추가할 때마다 언제나
+{@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 행을 추가합니다.
+ </dt>
+ <dd>
+ {@link android.provider.ContactsContract.Data} 테이블에 {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} 행이 없는 {@link android.provider.ContactsContract.RawContacts} 행이 있으면
+통합 과정에서
+문제가 발생할 수 있습니다.
+
+ </dd>
+ <dt>
+ 언제나 새로운 {@link android.provider.ContactsContract.Data} 행을
+해당 상위 {@link android.provider.ContactsContract.RawContacts} 행에 연결합니다.
+ </dt>
+ <dd>
+ {@link android.provider.ContactsContract.RawContacts}에 연결되지 않은 {@link android.provider.ContactsContract.Data} 행은
+기기 연락처 애플리케이션에 표시되지 않고,
+동기화 어댑터에서 문제를 발생시킬 수 있습니다.
+ </dd>
+ <dt>
+ 개발자 본인의 소유인 원시 연락처에 대한 데이터만 변경하십시오.
+ </dt>
+ <dd>
+ 연락처 제공자는 보통 여러 가지 서로 다른 계정 유형/온라인 서비스에서 가져온
+데이터를 관리한다는 점을 명심하십시오. 개발자의 애플리케이션은 본인에게
+속한 행에 대한 데이터만 수정 또는 삭제하도록 확실히 해두어야 하며, 데이터를 삽입할 때에도 개발자 본인이
+제어하는 계정 유형과 이름만 사용해야 합니다.
+ </dd>
+ <dt>
+ 권한, 콘텐츠 URI, URI 경로, 열 이름, MIME 유형 및
+{@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE} 값에 대해서는 항상
+{@link android.provider.ContactsContract} 및 그 하위 클래스에서 정의한 상수를 사용합니다.
+ </dt>
+ <dd>
+ 이런 상수를 사용하면 오류를 피하는 데 도움이 됩니다. 이런 상수 중 하나라도 사용하지 않게 되는 경우 컴파일러로부터
+알림을 받기도 합니다.
+ </dd>
+</dl>
+<h3 id="CustomData">사용자 지정 데이터 행</h3>
+<p>
+ 사용자 지정 MIME 유형을 생성하여 사용하면,
+{@link android.provider.ContactsContract.Data} 테이블에 있는 본인의 데이터 행을 삽입, 편집, 삭제 및 검색할 수 있습니다. 개발자의 행은
+{@link android.provider.ContactsContract.DataColumns}에서
+정의된 열만 사용하도록 제한되어 있습니다. 다만 나름의 유형별 열 이름을
+기본 열 이름에 매핑할 수는 있습니다. 기기의 연락처 애플리케이션에서는
+개발자의 행에 대한 데이터가 표시는 되지만 편집이나 삭제는 할 수 없고, 사용자가 추가 데이터를
+추가할 수도 없습니다. 사용자가 개발자의 사용자 지정 데이터 행을 수정하도록 허용하려면, 본인의 애플리케이션에
+편집기 액티비티를 제공해야 합니다.
+</p>
+<p>
+ 개발자의 사용자 지정 데이터를 표시하려면, <code>&lt;ContactsAccountType&gt;</code> 요소와 하나 이상의 <code>&lt;ContactsDataKind&gt;</code> 하위 요소를 포함하는 <code>contacts.xml</code> 파일을
+제공합니다.
+ 이 내용은
+<a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; element</code></a> 섹션에 자세히 설명되어 있습니다.
+</p>
+<p>
+ 사용자 지정 MIME 유형에 대해 자세히 알아보려면,
+<a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+콘텐츠 제공자 생성</a> 가이드를 참조하십시오.
+</p>
+<h2 id="SyncAdapters">연락처 제공자 동기화 어댑터</h2>
+<p>
+ 연락처 제공자는 기기와 온라인 서비스 사이에서 연락처 데이터의 <strong>동기화</strong>를
+처리한다는 구체적인 목적을 두고 디자인된 것입니다. 이것을 사용하면 사용자가 기존의
+데이터를 새 기기에 다운로드할 수도 있고, 기존의 데이터를 새 계정에 업로드할 수도 있습니다.
+ 동기화를 사용하면 사용자가 추가나 변경의 출처와 관계 없이 최신 데이터를
+편리하게 사용할 수 있게 보장하기도 합니다. 동기화의 또 다른 장점은
+기기가 네트워크에 연결되어 있지 않더라도 연락처 데이터를 사용할 수 있다는 것입니다.
+</p>
+<p>
+ 다양한 방식으로 동기화를 구현할 수 있지만, Android 시스템은
+플러그인 동기화 프레임워크를 제공하여 다음과 같은 작업들을 자동화해줍니다.
+ <ul>
+
+ <li>
+ 네트워크 가용성을 확인합니다.
+ </li>
+ <li>
+ 사용자 기본 설정에 따라 동기화를 예약하고 실행합니다.
+ </li>
+ <li>
+ 중단된 동기화를 다시 시작합니다.
+ </li>
+ </ul>
+<p>
+ 이 프레임워크를 사용하려면 동기화 어댑터 플러그인은 개발자가 직접 제공해야 합니다. 동기화 어댑터는
+서비스와 콘텐츠 제공자마다 각기 다르지만, 같은 서비스에 대해 여러 개의 계정 이름을 처리할 수 있습니다. 이
+프레임워크 또한 같은 서비스와 제공자에 대해 여러 개의 동기화 어댑터를 허용합니다.
+</p>
+<h3 id="SyncClassesFiles">동기화 어댑터 클래스 및 파일</h3>
+<p>
+ 동기화 어댑터를
+{@link android.content.AbstractThreadedSyncAdapter}의
+하위 클래스로 구현하고 이를Android 애플리케이션의 일부로 설치합니다. 시스템은 애플리케이션 매니페스트의 요소와 매니페스트가 가리키는
+특수 XML 파일에서 동기화 어댑터에 관한 정보를 얻습니다. XML 파일은
+온라인 서비스와 콘텐츠 제공자의 권한에 대한 계정 유형을 정의하고,
+이들이 함께 어댑터를 고유하게 식별합니다. 동기화 어댑터가 활성화되려면 사용자가
+동기화 어댑터의 계정 유형에 대해 계정을 추가하고 해당 동기화 어댑터와 동기화하는 콘텐츠 제공자의 동기화를
+활성화해야 합니다. 이 시점에서, 시스템이 어댑터 관리를 시작하고,
+콘텐츠 제공자와 서버 사이에서 동기화가 필요할 때 이를 호출합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 계정 유형을 동기화 어댑터 식별의 일부로 사용하면
+시스템이 동일한 같은 조직에서 여러 서비스에 액세스하는 동기화 어댑터를
+감지하고 그룹화할 수 있습니다. 예를 들어, Google 온라인 서비스의 동기화 어댑터는 계정 유형이 모두
+<code>com.google</code>로 같습니다. 사용자가 기기에 Google 계정을 추가하면,
+Google 서비스에 설치된 모든 동기화 어댑터가 함께 목록으로 표시됩니다. 목록에 게재된 각 동기화는
+기기에서 각기 다른 콘텐츠 제공자와 동기화합니다.
+</p>
+<p>
+ 대부분의 서비스에서는 사용자가 데이터에 액세스하기 전에
+ID를 확인해야 하기 때문에 Android에서는 동기화 어댑터 프레임워크와 비슷하면서 종종 이와 함께 쓰이기도 하는
+인증 프레임워크를 제공합니다. 인증 프레임워크는
+{@link android.accounts.AbstractAccountAuthenticator}의 하위 클래스인
+플러그인 인증자를 사용합니다. 인증자는 다음 절차에 따라
+사용자의 ID를 확인합니다.
+ <ol>
+ <li>
+ 사용자 이름, 암호 또는 유사한 정보(사용자의
+<strong>자격 증명</strong>)를 수집합니다.
+ </li>
+ <li>
+ 자격 증명을 서비스로 전송합니다.
+ </li>
+ <li>
+ 서비스의 회신을 검토합니다.
+ </li>
+ </ol>
+<p>
+ 서비스가 자격 증명을 수락하면
+인증자가 자격 증명을 저장하여 나중에 사용할 수 있습니다. 플러그인 인증자 프레임워크로 인해,
+{@link android.accounts.AccountManager}는 Oauth2 authToken과 같이 인증자가 지원하고 노출하기로 선택하는 모든 authToken에 액세스를
+제공합니다.
+</p>
+<p>
+ 인증이 꼭 필요한 것은 아니지만, 대부분의 연락처 서비스는 이를 사용합니다.
+ 다만, 인증을 수행하기 위해 꼭 Android 인증 프레임워크를 사용해야 하는 것은 아닙니다.
+</p>
+<h3 id="SyncAdapterImplementing">동기화 어댑터 구현</h3>
+<p>
+ 연락처 제공자에 대한 동기화 어댑터를 구현하려면,
+다음이 들어있는 Android 애플리케이션을 생성하는 것으로 시작합니다.
+</p>
+ <dl>
+ <dt>
+ 시스템의 요청에 응답하여 동기화 어댑터에 바인딩하는 {@link android.app.Service}
+구성 요소.
+ </dt>
+ <dd>
+ 시스템이 동기화를 실행하고자 하는 경우, 이는
+서비스의 {@link android.app.Service#onBind(Intent) onBind()} 메서드를 호출하여
+동기화 어댑터의 {@link android.os.IBinder}를 가져옵니다. 이렇게 하면 시스템이 어댑터의
+메서드에 대해 프로세스간 호출을 수행할 수 있습니다.
+ <p>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+샘플 동기화 어댑터</a> 샘플 앱에서 이 서비스의 클래스 이름은
+<code>com.example.android.samplesync.syncadapter.SyncService</code>입니다.
+ </p>
+ </dd>
+ <dt>
+ {@link android.content.AbstractThreadedSyncAdapter}의
+하위 클래스로 구현된 실제 동기화 어댑터.
+ </dt>
+ <dd>
+ 이 클래스는 서버에서 데이터를 다운로드하고, 기기에서 데이터를 업로드하고,
+충돌을 해결하는 작업을 수행합니다. 어댑터의 주요 작업은
+{@link android.content.AbstractThreadedSyncAdapter#onPerformSync(
+Account, Bundle, String, ContentProviderClient, SyncResult)
+onPerformSync()} 메서드에서 실행합니다. 이 클래스는 반드시 단일 항목으로 인스턴트화해야 합니다.
+ <p>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+샘플 동기화 어댑터</a> 샘플 앱에서 동기화 어댑터는
+<code>com.example.android.samplesync.syncadapter.SyncAdapter</code> 클래스에서 정의됩니다.
+ </p>
+ </dd>
+ <dt>
+ {@link android.app.Application}의 하위 클래스.
+ </dt>
+ <dd>
+ 이 클래스는 동기화 어댑터 단일 항목의 팩터리 역할을 합니다.
+{@link android.app.Application#onCreate()} 메서드는
+동기화 어댑터를 인스턴트화하고, 단일 항목을 동기화 어댑터 서비스의
+{@link android.app.Service#onBind(Intent) onBind()} 메서드에 반환할 정적 "getter" 메서드를 제공하는 데
+사용하십시오.
+ </dd>
+ <dt>
+ <strong>선택 항목:</strong> 사용자 인증에 대한 시스템으로부터의 요청에 응답하는 {@link android.app.Service}
+구성 요소.
+ </dt>
+ <dd>
+ {@link android.accounts.AccountManager}가 이 서비스를 시작하여 인증
+절차를 시작합니다. 서비스의 {@link android.app.Service#onCreate()} 메서드가
+인증자 객체를 인스턴트화합니다. 시스템이 애플리케이션 동기화 어댑터의 사용자 계정을 인증하고자 하는 경우,
+시스템은 서비스의
+{@link android.app.Service#onBind(Intent) onBind()} 메서드를 호출하여
+인증자의 {@link android.os.IBinder}를 가져옵니다. 이렇게 하면 시스템이 인증자의
+메서드에 대해 프로세스간 호출을 수행할 수 있습니다.
+ <p>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+샘플 동기화 어댑터</a> 샘플 앱에서 이 서비스의 클래스 이름은
+<code>com.example.android.samplesync.authenticator.AuthenticationService</code>입니다.
+ </p>
+ </dd>
+ <dt>
+ <strong>선택 항목:</strong> 인증에 대한 요청을 처리하는
+{@link android.accounts.AbstractAccountAuthenticator}의 구체적인
+하위 클래스.
+ </dt>
+ <dd>
+ 이 클래스는 {@link android.accounts.AccountManager}가
+서버로 사용자 자격 증명 인증을 호출하는 메서드를 제공합니다. 인증 절차의 세부 사항은
+사용하는 서버 기술에 따라 매우 차이가 있습니다. 인증에 대한
+자세한 정보는 각자의 서버 소프트웨어에 해당되는 관련 문서를 참조하십시오.
+ <p>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+샘플 동기화 어댑터</a> 샘플 앱에서 인증자는
+<code>com.example.android.samplesync.authenticator.Authenticator</code> 클래스에서 정의됩니다.
+ </p>
+ </dd>
+ <dt>
+ 동기화 어댑터와 서버의 인증자를 정의하는 XML 파일.
+ </dt>
+ <dd>
+ 이전에 설명한 동기화 어댑터와 인증자 서비스 구성 요소는
+애플리케이션 매니페스트의
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code> 요소에서
+정의합니다. 이런 요소에는
+시스템에 특정 데이터를 제공하는
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+하위 요소가
+들어있습니다.
+ <ul>
+ <li>
+ 동기화 어댑터 서비스에 대한
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+요소는
+XML 파일 <code>res/xml/syncadapter.xml</code>을 가리킵니다. 그런가 하면
+이 파일은 연락처 제공자와 동기화될 웹 서비스에 대한 URI와 웹 서비스에 대한 계정 유형을
+나타냅니다.
+ </li>
+ <li>
+ <strong>선택 항목:</strong> 인증자의
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+요소는 XML 파일
+<code>res/xml/authenticator.xml</code>을 가리킵니다. 이 파일은 다시
+이 인증이 지원하는 계정 유형과, 인증 과정 중에 표시되는 UI 리소스를
+나타냅니다. 이 요소에서 지정한 계정 유형은 반드시
+동기화 어댑터에 대해 지정된 계정 유형과
+같아야 합니다.
+ </li>
+ </ul>
+ </dd>
+ </dl>
+<h2 id="SocialStream">소셜 스트림 데이터</h2>
+<p>
+ {@code android.provider.ContactsContract.StreamItems}와
+{@code android.provider.ContactsContract.StreamItemPhotos} 테이블은
+소셜 네트워크에서 수신하는 데이터를 관리합니다. 개발자는 본인의 네트워크의 스트림 데이터를 이 테이블에 추가하는
+동기화 어댑터를 작성할 수도 있고, 이 테이블에서 스트림 데이터를 읽어서
+본인의 애플리케이션에 표시할 수도 있으며 두 가지를 모두 해도 됩니다. 이 기능을 사용하면 소셜 네트워킹
+서비스와 애플리케이션을 Android의 소셜 네트워킹 환경에 통합할 수 있습니다.
+</p>
+<h3 id="StreamText">소셜 스트림 텍스트</h3>
+<p>
+ 스트림 항목은 항상 원시 연락처와 연관됩니다.
+{@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}는
+원시 연락처의 <code>_ID</code> 값과 연관됩니다. 원시 연락처의 계정 유형과 계정 이름도
+스트림 항목 행에 저장됩니다.
+</p>
+<p>
+ 스트림에서 가져온 데이터는 다음 열에 저장합니다.
+</p>
+<dl>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE}
+ </dt>
+ <dd>
+ <strong>필수입니다.</strong> 이 스트림 항목과 연관된 원시 연락처에 대한
+사용자 계정입니다. 스트림 항목을 삽입할 때 이 값을 설정하는 것을 잊지 마십시오.
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME}
+ </dt>
+ <dd>
+ <strong>필수입니다.</strong> 이 스트림 항목과 연관된 원시 연락처에 대한
+사용자 계정 이름입니다. 스트림 항목을 삽입할 때 이 값을 설정하는 것을 잊지 마십시오.
+ </dd>
+ <dt>
+ 식별자 열
+ </dt>
+ <dd>
+ <strong>필수입니다.</strong> 스트림 항목을 삽입할 때
+다음 식별자 열을 삽입해야 합니다.
+ <ul>
+ <li>
+ {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: 이
+스트림 항목과 연관된 연락처의 {@code android.provider.BaseColumns#_ID}
+값입니다.
+ </li>
+ <li>
+ {@code android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: 이
+스트림 항목과 연관된 연락처의 {@code android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}
+값입니다.
+ </li>
+ <li>
+ {@code android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: 이
+스트림 항목과 연관된 원시 연락처의 {@code android.provider.BaseColumns#_ID}
+값입니다.
+ </li>
+ </ul>
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemsColumns#COMMENTS}
+ </dt>
+ <dd>
+ 선택 사항입니다. 스트림 항목의 시작 부분에 표시할 수 있는 요약 정보를 저장합니다.
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemsColumns#TEXT}
+ </dt>
+ <dd>
+ 스트림 항목의 텍스트로, 항목의 소스가 게시한 콘텐츠 또는
+스트림 항목을 생성하는 작업의 설명 중 하나입니다. 이 열에는
+{@link android.text.Html#fromHtml(String) fromHtml()}가 렌더링할 수 있는 모든 서식과 포함된 리소스 이미지가
+들어있을 수 있습니다. 제공자는 긴 콘텐츠를
+자르거나 생략할 수 있지만, 가능하면 태그를 손상시키는 것은 피하려 듭니다.
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}
+ </dt>
+ <dd>
+ 스트림 항목이 삽입되거나 업데이트된 시간이 들어있는 텍스트 문자열로, 형식은
+epoch 이후 <em>밀리초</em> 형태를 취합니다. 이 열을 관리할 책임은
+스트림 항목을 삽입 또는 업데이트하는 애플리케이션에 있으며, 이것은 연락처 제공자가 자동으로
+유지 관리하지 않습니다.
+ </dd>
+</dl>
+<p>
+ 스트림 항목의 식별 정보를 표시하려면
+{@code android.provider.ContactsContract.StreamItemsColumns#RES_ICON},
+{@code android.provider.ContactsContract.StreamItemsColumns#RES_LABEL},
+{@code android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE}를 사용하여 애플리케이션에서
+리소스를 연결하십시오.
+</p>
+<p>
+ {@code android.provider.ContactsContract.StreamItems} 테이블에도
+동기화 어댑터가 독점적으로 사용하는 {@code android.provider.ContactsContract.StreamItemsColumns#SYNC1}에서
+{@code android.provider.ContactsContract.StreamItemsColumns#SYNC4}까지의 열이
+들어있습니다.
+</p>
+<h3 id="StreamPhotos">소셜 스트림 사진</h3>
+<p>
+ {@code android.provider.ContactsContract.StreamItemPhotos} 테이블은 스트림 항목과 연관된
+사진을 저장합니다. 테이블의
+{@code android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} 열은
+{@code android.provider.ContactsContract.StreamItems} 테이블의 {@code android.provider.BaseColumns#_ID} 열에 있는 값과
+연결됩니다. 사진 참조는
+다음 열의 테이블에 저장됩니다.
+</p>
+<dl>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemPhotos#PHOTO} 열(BLOB).
+ </dt>
+ <dd>
+ 사진의 바이너리 표현으로, 제공자가 저장하고 표시하기 위해 크기를 조정한 것입니다.
+ 이 열은 사진을 저장하는 데 사용한 연락처 제공자의 이전 버전과
+호환됩니다. 그러나 현재 버전에서는
+이 열을 사진 저장에 사용하면 안 됩니다. 대신,
+{@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} 또는
+{@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}(
+다음 항목에서 두 가지 모두 설명)를 사용하여 사진을 파일로 저장합니다. 지금 이 열에는
+사진의 미리 보기가 들어있어 읽기 작업에 사용할 수 있습니다.
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID}
+ </dt>
+ <dd>
+ 원시 연락처에 대한 사진의 숫자 식별자입니다. 이 값을
+상수 {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI}에 추가하여
+하나의 사진 파일을 가리키는 콘텐츠 URI를 가져온 다음,
+{@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
+openAssetFileDescriptor()}를 호출하여 사진 파일에 대한 핸들을 가져옵니다.
+ </dd>
+ <dt>
+ {@code android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}
+ </dt>
+ <dd>
+ 이 행이 나타내는 사진에 대한 사진 파일을 직접 가리키는 콘텐츠 URI입니다.
+ 이 URI로 {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
+openAssetFileDescriptor()}를 호출하면 사진 파일에 대한 핸들을 가져올 수 있습니다.
+ </dd>
+</dl>
+<h3 id="SocialStreamTables">소셜 스트림 테이블 사용</h3>
+<p>
+ 이들 테이블은 연락처 제공자의 다른 주요 테이블과 똑같이 작동하지만, 다음 예외가 적용됩니다.
+</p>
+ <ul>
+ <li>
+ 이 테이블에는 추가 액세스 권한이 필요합니다. 여기서 읽기 작업을 수행하려면 애플리케이션에
+{@code android.Manifest.permission#READ_SOCIAL_STREAM} 권한이 있어야 합니다. 여기서 수정 작업을 수행하려면
+애플리케이션에
+{@code android.Manifest.permission#WRITE_SOCIAL_STREAM} 권한이 있어야 합니다.
+ </li>
+ <li>
+ {@code android.provider.ContactsContract.StreamItems} 테이블의 경우, 각 원시 연락처에 저장되는
+행 개수가 제한되어 있습니다. 이 한계에 도달하면,
+연락처 제공자가 새 스트림 항목 열에 필요한 공간을 만들어야 합니다.
+이때 가장 오래된 {@code android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}가
+있는 행부터 자동으로 삭제하는 방법을 씁니다. 이 한계를
+가져오려면, 콘텐츠 URI
+{@code android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}에 쿼리를 발행합니다. 콘텐츠
+URI를 뺀 나머지 모든 인수는 <code>null</code>로 설정한 채 두면 됩니다. 이 쿼리는
+행이 하나 들어 있는 커서를 반환하며,
+{@code android.provider.ContactsContract.StreamItems#MAX_ITEMS} 열 하나가 수반됩니다.
+ </li>
+ </ul>
+
+<p>
+ {@code android.provider.ContactsContract.StreamItems.StreamItemPhotos} 클래스는
+스트림 항목 하나의 사진 행을 포함하는 {@code android.provider.ContactsContract.StreamItemPhotos}의
+하위 테이블을 정의합니다.
+</p>
+<h3 id="SocialStreamInteraction">소셜 스트림 상호 작용</h3>
+<p>
+ 연락처 제공자가 기기 연락처 애플리케이션과 함께 관리하는 소셜 스트림 데이터는
+소셜 네트워킹 시스템과
+기존 연락처를 연결하는 강력한 방법을 제공합니다. 사용할 수 있는 기능은 다음과 같습니다.
+</p>
+ <ul>
+ <li>
+ 소셜 네트워킹 서비스를 동기화 어댑터로 연락처 제공자에 동기화함으로써,
+사용자 연락처의 최근 활동을 검색하고 이를
+{@code android.provider.ContactsContract.StreamItems} 및
+{@code android.provider.ContactsContract.StreamItemPhotos} 테이블에 저장해 두어 나중에 사용할 수 있습니다.
+ </li>
+ <li>
+ 정기 동기화 외에도 사용자가 볼 연락처를 선택하면 동기화 어댑터를 트리거하여
+추가 데이터를 검색하게 할 수 있습니다. 이렇게 하면 동기화 어댑터가
+해당 연락처의 고해상도 사진과 가장 최근 스트림 항목을 검색할 수 있습니다.
+ </li>
+ <li>
+ 기기 연락처 애플리케이션과 연락처 제공자에 알림을 등록하면,
+연락처가 열람될 때 인텐트를 <em>수신</em>하고,
+그 시점에 개발자의 서비스로부터 연락처의 상태를 업데이트할 수 있습니다. 이 방법을 사용하면 동기화 어댑터로
+완전 동기화를 수행하는 것보다 빠르고 대역폭도 적게 사용합니다.
+ </li>
+ <li>
+ 사용자는 기기의 연락처 애플리케이션을 보면서 여러분의 소셜 네트워킹 서비스에
+연락처를 추가할 수 있습니다. 이는 "연락처 초대" 기능으로 사용할 수 있습니다.
+연락처 초대 기능은 기존 연락처를 네트워크에 추가하는 액티비티와
+기기의 연락처 애플리케이션을 제공하는 XML 파일,
+애플리케이션의 세부 정보가 포함된 연락처 제공자를 조합하여 활성화합니다.
+ </li>
+ </ul>
+<p>
+ 연락처 제공자로 스트림 항목을 정기 동기화하는 방법은
+다른 동기화와 같습니다. 동기화에 관한 자세한 내용은
+<a href="#SyncAdapters">연락처 제공자 동기화 어댑터</a> 섹션을 참조하십시오. 알림을 등록하고 연락처를 초대하는 방법은
+다음 두 섹션에서 다룰 것입니다.
+</p>
+<h4>소셜 네트워킹 보기를 처리하기 위한 등록</h4>
+<p>
+ 동기화 어댑터를 등록하여 사용자가 동기화 어댑터에서 관리하는 연락처를 볼 때 알림을
+수신하는 방법:
+</p>
+<ol>
+ <li>
+ 프로젝트의 <code>res/xml/</code> 디렉터리에 <code>contacts.xml</code> 파일을
+만듭니다. 이미 이 파일이 있다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 이 파일에서,
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> 요소를 추가합니다.
+ 이 요소가 이미 존재한다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 사용자가 기기의 연락처 애플리케이션에서
+연락처 세부 정보 페이지를 열면 알림을 보내는 서비스를 등록하려면,
+<code>viewContactNotifyService="<em>serviceclass</em>"</code> 속성을 요소에 추가합니다.
+이 요소에서 <code><em>serviceclass</em></code>는 기기의 연락처 애플리케이션에서 인텐트를 수신하는 서비스의
+완전히 정규화된 클래스 이름입니다. 알림 서비스의 경우,
+{@link android.app.IntentService}를 확장하는 클래스를 사용하여 서비스가 인텐트를 수신하도록
+허용합니다. 수신되는 인텐트의 데이터에는
+사용자가 클릭한 원시 연락처의 콘텐츠 URI가 들어있습니다. 알림 서비스에서 동기화 어댑터에 바인딩한 다음 동기화 어댑터를 호출하여
+원시 연락처의 데이터를 업데이트할 수 있습니다.
+ </li>
+</ol>
+<p>
+ 사용자가 스트림 항목이나 사진, 또는 그 두 가지를 모두 클릭할 때 호출할 액티비티를 등록하는 방법:
+</p>
+<ol>
+ <li>
+ 프로젝트의 <code>res/xml/</code> 디렉터리에 <code>contacts.xml</code> 파일을
+만듭니다. 이미 이 파일이 있다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 이 파일에서,
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> 요소를 추가합니다.
+ 이 요소가 이미 존재한다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 사용자가 기기의 연락처 애플리케이션에서 스트림 항목을 클릭했을 때
+처리할 액티비티를 등록하려면,
+<code>viewStreamItemActivity="<em>activityclass</em>"</code> 속성을 요소에 추가합니다.
+이 요소에서 <code><em>activityclass</em></code>는 기기의 연락처 애플리케이션에서 인텐트를 수신하는 액티비티의
+완전히 정규화된 클래스 이름입니다.
+ </li>
+ <li>
+ 사용자가 기기의 연락처 애플리케이션에서 스트림 사진을 클릭했을 때
+처리할 액티비티를 등록하려면,
+<code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> 속성을 요소에 추가합니다.
+이 요소에서 <code><em>activityclass</em></code>는 기기의 연락처 애플리케이션에서 인텐트를 수신하는 액티비티의
+완전히 정규화된 클래스 이름입니다.
+ </li>
+</ol>
+<p>
+ <code>&lt;ContactsAccountType&gt;</code> 요소는
+<a href="#SocialStreamAcctType">&lt;ContactsAccountType&gt; 요소</a> 섹션에 자세히 설명되어 있습니다.
+</p>
+<p>
+ 수신되는 인텐트에 사용자가 클릭한 항목 또는 사진의 콘텐츠 URI가 들어있습니다.
+ 텍스트 항목과 사진에 각기 별도의 액티비티를 적용하려면, 두 속성을 모두 같은 파일에서 사용하십시오.
+</p>
+<h4>소셜 네트워킹 서비스로 상호 작용</h4>
+<p>
+ 사용자는 소셜 네트워킹 사이트에 연락처를 초대할 때
+기기의 연락처 애플리케이션을 떠나지 않아도 됩니다. 대신, 개발자가 기기의 연락처 앱에 액티비티 중 하나로 연락처를 초대하는 인텐트를
+보내게 할 수 있습니다. 이렇게 설정하는 방법은 다음과 같습니다.
+</p>
+<ol>
+ <li>
+ 프로젝트의 <code>res/xml/</code> 디렉터리에 <code>contacts.xml</code> 파일을
+만듭니다. 이미 이 파일이 있다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 이 파일에서,
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code> 요소를 추가합니다.
+ 이 요소가 이미 존재한다면 이 절차를 건너뛰어도 됩니다.
+ </li>
+ <li>
+ 다음 속성을 추가합니다.
+ <ul>
+ <li><code>inviteContactActivity="<em>activityclass</em>"</code></li>
+ <li>
+ <code>inviteContactActionLabel="&#64;string/<em>invite_action_label</em>"</code>
+ </li>
+ </ul>
+ <code><em>activityclass</em></code> 값은 인텐트를 수신해야 하는 액티비티의
+완전히 정규화된 클래스 이름입니다. <code><em>invite_action_label</em></code>
+값은 기기의 연락처 애플리케이션에 있는 <strong>연결 추가</strong> 메뉴에
+표시되는 텍스트 문자열입니다.
+ </li>
+</ol>
+<p class="note">
+ <strong>참고:</strong> <code>ContactsSource</code>는
+<code>ContactsAccountType</code>에 대하여 이제 사용하지 않는 태그 이름입니다.
+</p>
+<h3 id="ContactsFile">contacts.xml 참조</h3>
+<p>
+ <code>contacts.xml</code> 파일에는 XML 요소가 들어있어 개발자의 동기화 어댑터와
+애플리케이션, 연락처 애플리케이션과 연락처 제공자 사이의 상호 작용을 제어합니다. 이런
+요소는 다음 섹션에 설명되어 있습니다.
+</p>
+<h4 id="SocialStreamAcctType">&lt;ContactsAccountType&gt; 요소</h4>
+<p>
+ <code>&lt;ContactsAccountType&gt;</code>요 요소는 개발자의 애플리케이션과
+연락처 애플리케이션 사이의 상호 작용을 제어합니다. 이 요소에는 다음 구문이 있습니다.
+</p>
+<pre>
+&lt;ContactsAccountType
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ inviteContactActivity="<em>activity_name</em>"
+ inviteContactActionLabel="<em>invite_command_text</em>"
+ viewContactNotifyService="<em>view_notify_service</em>"
+ viewGroupActivity="<em>group_view_activity</em>"
+ viewGroupActionLabel="<em>group_action_text</em>"
+ viewStreamItemActivity="<em>viewstream_activity_name</em>"
+ viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"&gt;
+</pre>
+<p>
+ <strong>포함 장소:</strong>
+</p>
+<p>
+ <code>res/xml/contacts.xml</code>
+</p>
+<p>
+ <strong>포함 가능 요소:</strong>
+</p>
+<p>
+ <strong><code>&lt;ContactsDataKind&gt;</code></strong>
+</p>
+<p>
+ <strong>설명:</strong>
+</p>
+<p>
+ 사용자가 연락처 중 하나를 소셜 네트워크에 초대하고,
+소셜 네트워킹 스트림이 업데이트되면 사용자에게 알리는 등의 작업을 허용하는
+Android 구성 요소와 UI 레이블을 선언합니다.
+</p>
+<p>
+ 속성 접두사 <code>android:</code>는
+<code>&lt;ContactsAccountType&gt;</code>의 속성에는 필요하지 않다는 점을 눈여겨보십시오.
+</p>
+<p>
+ <strong>속성:</strong>
+</p>
+<dl>
+ <dt>{@code inviteContactActivity}</dt>
+ <dd>
+ 사용자가 기기의 연락처 애플리케이션에서
+<strong>연결 추가</strong>를 선택했을 때 활성화하고자 하는
+애플리케이션 액티비티의 완전히 정규화된 클래스 이름입니다.
+ </dd>
+ <dt>{@code inviteContactActionLabel}</dt>
+ <dd>
+ <strong>연결 추가</strong> 메뉴의
+{@code inviteContactActivity}에서 지정된 액티비티에 대해 표시되는 텍스트 문자열입니다.
+ 예를 들어, 문자열 "제 네트워크를 팔로우하세요"를 사용할 수 있습니다. 이 레이블에 대한 문자열 리소스
+식별자를 사용할 수 있습니다.
+ </dd>
+ <dt>{@code viewContactNotifyService}</dt>
+ <dd>
+ 사용자가 연락처를 볼 때 알림을 수신해야 하는
+애플리케이션 서비스의 완전히 정규화된 클래스 이름입니다. 이 알림은
+기기의 연락처 애플리케이션이 전송합니다. 이것을 사용하면 개발자의 애플리케이션이 데이터 집약적인 작업을 필요할 때까지
+연기할 수 있습니다. 예를 들어, 개발자의 애플리케이션은
+연락처의 고해상도 사진과 가장 최근 소셜 스트림 항목을 읽어서 표시함으로써
+이 알림에 응답할 수 있습니다. 이 기능은
+<a href="#SocialStreamInteraction">소셜 스트림 상호 작용</a>에 상세히 설명되어 있습니다. 알림 서비스의 예시를
+보려면 <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>
+ 샘플 앱에 있는 <code>NotifierService.java</code> 파일을
+확인합니다.
+ </dd>
+ <dt>{@code viewGroupActivity}</dt>
+ <dd>
+ 그룹 정보를 표시할 수 있는 애플리케이션 액티비티의
+완전히 정규화된 클래스 이름입니다. 사용자가 기기의 연락처 애플리케이션에서 그룹 레이블을 클릭하면,
+이 액티비티의 UI가 표시됩니다.
+ </dd>
+ <dt>{@code viewGroupActionLabel}</dt>
+ <dd>
+ 사용자가 개발자의 애플리케이션에서 그룹을 살펴볼 수 있도록 해주는 UI 제어에 대해
+연락처 애플리케이션이 표시하는 레이블입니다.
+ <p>
+ 예를 들어, 기기에 Google+ 애플리케이션을 설치하고
+Google+를 연락처 애플리케이션과 동기화하면, Google+ 서클이
+연락처 애플리케이션의 <strong>그룹</strong> 탭에 표시되는 것을 볼 수 있습니다. Google+ 서클을
+클릭하면 해당 서클에서 "그룹"으로 표시된 사람들을 볼 수 있습니다. 이 표시의 맨 위에
+Google+ 아이콘이 표시되며, 이것을 클릭하면 제어가
+Google+ 앱으로 전환됩니다. 연락처 애플리케이션은 이 작업을
+{@code viewGroupActivity}로 수행하며, Google+ 아이콘을
+{@code viewGroupActionLabel}의 값으로 사용합니다.
+ </p>
+ <p>
+ 이 속성에서는 문자열 리소스 식별자가 허용됩니다.
+ </p>
+ </dd>
+ <dt>{@code viewStreamItemActivity}</dt>
+ <dd>
+ 사용자가 원시 연락처의 스트림 항목을 클릭할 때 기기의 연락처 애플리케이션이 시작하는
+애플리케이션 액티비티의 완전히 정규화된 클래스 이름입니다.
+ </dd>
+ <dt>{@code viewStreamItemPhotoActivity}</dt>
+ <dd>
+ 사용자가 원시 연락처 스트림 항목의 사진을 클릭할 때
+기기의 연락처 애플리케이션이 시작하는 애플리케이션 액티비티의
+완전히 정규화된 클래스 이름입니다.
+ </dd>
+</dl>
+<h4 id="SocialStreamDataKind">&lt;ContactsDataKind&gt; 요소</h4>
+<p>
+ <code>&lt;ContactsDataKind&gt;</code> 요소는 연락처 애플리케이션 UI에서 애플리케이션의 사용자 지정 데이터 행 표시를
+제어합니다. 이 요소에는 다음 구문이 있습니다.
+</p>
+<pre>
+&lt;ContactsDataKind
+ android:mimeType="<em>MIMEtype</em>"
+ android:icon="<em>icon_resources</em>"
+ android:summaryColumn="<em>column_name</em>"
+ android:detailColumn="<em>column_name</em>"&gt;
+</pre>
+<p>
+ <strong>포함 장소:</strong>
+</p>
+<code>&lt;ContactsAccountType&gt;</code>
+<p>
+ <strong>설명:</strong>
+</p>
+<p>
+ 이 요소를 사용하여 연락처 애플리케이션이 사용자 지정 데이터 행의 콘텐츠를
+원시 연락처 세부 정보의 일부로 표시하게 합니다. <code>&lt;ContactsAccountType&gt;</code>의 각 <code>&lt;ContactsDataKind&gt;</code> 하위 요소는
+동기화 어댑터가 {@link android.provider.ContactsContract.Data}에 추가하는
+사용자 지정 데이터 행의 유형을 나타냅니다. 개발자가 사용하는 사용자 지정 MIME 유형 하나마다
+<code>&lt;ContactsDataKind&gt;</code> 요소를 하나씩 추가합니다. 데이터를
+표시하는 것을 원치 않는 사용자 지정 데이터 행이 있으면, 이 요소를 추가하지 않아도 됩니다.
+</p>
+<p>
+ <strong>속성:</strong>
+</p>
+<dl>
+ <dt>{@code android:mimeType}</dt>
+ <dd>
+ {@link android.provider.ContactsContract.Data} 테이블에서
+사용자 지정 데이터 행 유형 중 하나로 지정한 사용자 지정 MIME 유형입니다. 예를 들어,
+<code>vnd.android.cursor.item/vnd.example.locationstatus</code> 값은 연락처의 마지막으로 알려진 위치를 기록하는
+데이터 행에 대한 사용자 지정 MIME 유형이 될 수 있습니다.
+ </dd>
+ <dt>{@code android:icon}</dt>
+ <dd>
+ 연락처 애플리케이션이 개발자의 데이터 옆에 표시하는
+Android <a href="{@docRoot}guide/topics/resources/drawable-resource.html">드로어블 리소스</a>
+입니다. 이 리소스를 사용하여 사용자에게
+데이터 출처가 개발자의 서비스임을 나타내는 것입니다.
+ </dd>
+ <dt>{@code android:summaryColumn}</dt>
+ <dd>
+ 데이터 행에서 검색한 두 개 값 중에서 첫 번째 값에 대한 열 이름입니다. 이 값은
+이 데이터 행에 대한 항목의 첫 번째 줄로 표시됩니다. 첫 번째 줄은
+데이터 요약으로 사용되는 것이 본 목적이지만, 이것은 선택 사항입니다.
+<a href="#detailColumn">android:detailColumn</a>도 참조하십시오.
+ </dd>
+ <dt>{@code android:detailColumn}</dt>
+ <dd>
+ 데이터 행에서 검색한 두 개 값 중에서 두 번째 값에 대한 열 이름입니다. 이 값은
+이 데이터 행에 대한 항목의 두 번째 줄로 표시됩니다.
+{@code android:summaryColumn}도 참조하십시오.
+ </dd>
+</dl>
+<h2 id="AdditionalFeatures">추가 연락처 제공자 기능</h2>
+<p>
+ 이전 섹션에서 설명한 주요 기능 외에도 연락처 제공자는 연락처 데이터를 다루는 데
+유용한 기능을 많이 제공합니다. 예를 들면 다음과 같습니다.
+</p>
+ <ul>
+ <li>연락처 그룹</li>
+ <li>사진 기능</li>
+ </ul>
+<h3 id="Groups">연락처 그룹</h3>
+<p>
+ 연락처 제공자는 관련된 연락처 컬렉션에
+<strong>그룹</strong> 데이터로 레이블을 붙이기로 선택할 수 있습니다. 사용자 계정과 연관된 서버에서
+그룹을 관리하고자 하는 경우, 계정의 계정 유형에 대한 동기화 어댑터가
+연락처 제공자와 서버 사이에서 그룹 데이터를 전송해야 합니다. 사용자가 해당 서버에 새 연락처를 추가하고
+이 연락처를 새 그룹에 넣으면, 동기화 어댑터가 해당 새 그룹을
+{@link android.provider.ContactsContract.Groups} 테이블에 추가해야 합니다. 원시 연락처가 속한 그룹(또는 여러 그룹)은
+{@link android.provider.ContactsContract.Data} 테이블에 저장되며, 이때
+{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} MIME 유형을 사용합니다.
+</p>
+<p>
+ 개발자가 서버에서 가져온 원시 연락처 데이터를 연락처 제공자에 추가할
+동기화 어댑터를 디자인하는 중이고 그룹은 사용하지 않는다면,
+제공자 쪽에 데이터를 표시하라고 지시해야 합니다. 사용자가 기기에 계정을 추가했을 때 실행되는 코드에서
+연락처 제공자가 계정에 추가하는{@link android.provider.ContactsContract.Settings} 행을
+업데이트하십시오. 이 행에서
+{@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE
+Settings.UNGROUPED_VISIBLE} 열의 값을 1로 설정합니다. 이렇게 하면 연락처 제공자가
+개발자의 연락처 데이터를 항상 표시하게 되고, 이는 그룹을 사용하지 않더라도 관계 없습니다.
+</p>
+<h3 id="Photos">연락처 사진</h3>
+<p>
+ {@link android.provider.ContactsContract.Data} 테이블은
+{@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
+Photo.CONTENT_ITEM_TYPE} MIME 유형으로 사진을 행에 저장합니다. 이 행의
+{@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} 열은
+행이 속한 원시 연락처의 {@code android.provider.BaseColumns#_ID} 열과 연결됩니다.
+ 클래스 {@link android.provider.ContactsContract.Contacts.Photo}는
+연락처 기본 사진의 사진 정보가 들어있는 {@link android.provider.ContactsContract.Contacts} 하위 테이블을 정의합니다.
+연락처의 기본 사진은 연락처 기본 원시 연락처의 기본 사진입니다. 마찬가지로,
+{@link android.provider.ContactsContract.RawContacts.DisplayPhoto} 클래스는
+원시 연락처의 기본 사진의 사진 정보가 들어있는 {@link android.provider.ContactsContract.RawContacts} 하위 테이블을
+정의합니다.
+</p>
+<p>
+ {@link android.provider.ContactsContract.Contacts.Photo} 및
+{@link android.provider.ContactsContract.RawContacts.DisplayPhoto}에 대한 참조 문서에
+사진 정보를 검색하는 예시가 들어있습니다. 원시 연락처에 대한 기본 미리 보기를 검색하는 데 쓰이는
+편의 클래스는 없습니다. 하지만
+{@link android.provider.ContactsContract.Data} 테이블에 쿼리를 보내 원시 연락처의
+{@code android.provider.BaseColumns#_ID},
+ {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
+ Photo.CONTENT_ITEM_TYPE}, 및 {@link android.provider.ContactsContract.Data#IS_PRIMARY}
+ 열을 선택하면 해당 원시 연락처의 기본 사진 행을 찾을 수 있습니다.
+</p>
+<p>
+ 한 사람의 소셜 스트림 데이터에도 사진이 포함되어 있을 수 있습니다. 이런 사진은
+{@code android.provider.ContactsContract.StreamItemPhotos} 테이블에 저장되며, 이 내용은
+<a href="#StreamPhotos">소셜 스트림 사진</a>에 더 자세하게 설명되어 있습니다.
+</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/content-provider-basics.jd b/docs/html-intl/intl/ko/guide/topics/providers/content-provider-basics.jd
new file mode 100644
index 000000000000..953f92ab3026
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/content-provider-basics.jd
@@ -0,0 +1,1196 @@
+page.title=콘텐츠 제공자 기본 정보
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<!-- In this document -->
+<h2>이 문서의 내용</h2>
+<ol>
+ <li>
+ <a href="#Basics">개요</a>
+ <ol>
+ <li>
+ <a href="#ClientProvider">제공자 액세스</a>
+ </li>
+ <li>
+ <a href="#ContentURIs">콘텐츠 URI</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#SimpleQuery">제공자에서 데이터 검색</a>
+ <ol>
+ <li>
+ <a href="#RequestPermissions">읽기 액세스 권한 요청</a>
+ </li>
+ <li>
+ <a href="#Query">쿼리 구성</a>
+ </li>
+ <li>
+ <a href="#DisplayResults">쿼리 결과 표시</a>
+ </li>
+ <li>
+ <a href="#GettingResults">쿼리 결과에서 데이터 가져오기</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#Permissions">콘텐츠 제공자 권한</a>
+ </li>
+ <li>
+ <a href="#Modifications">데이터 삽입, 업데이트 및 삭제</a>
+ <ol>
+ <li>
+ <a href="#Inserting">데이터 삽입</a>
+ </li>
+ <li>
+ <a href="#Updating">데이터 업데이트</a>
+ </li>
+ <li>
+ <a href="#Deleting">데이터 삭제</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#DataTypes">제공자 데이터 유형</a>
+ </li>
+ <li>
+ <a href="#AltForms">제공자 액세스의 대체 형식</a>
+ <ol>
+ <li>
+ <a href="#Batch">일괄 액세스</a>
+ </li>
+ <li>
+ <a href="#Intents">인텐트를 통한 데이터 액세스</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClasses">계약 클래스</a>
+ </li>
+ <li>
+ <a href="#MIMETypeReference">MIME 유형 참조</a>
+ </li>
+</ol>
+
+ <!-- Key Classes -->
+<h2>Key 클래스</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.content.ContentResolver}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+
+ <!-- Related Samples -->
+<h2>관련 샘플</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ 커서(피플)</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ 커서(전화)</a>
+ </li>
+ </ol>
+
+ <!-- See also -->
+<h2>참고 항목</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ 콘텐츠 제공자 생성</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ 캘린더 제공자</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+ <!-- Intro paragraphs -->
+<p>
+ 콘텐츠 제공자는 데이터의 중앙 리포지토리로의 액세스를 관리합니다.
+제공자는 Android 애플리케이션의 일부이며, 이는 종종 나름의 UI를 제공하여 데이터에 작용하도록 합니다.
+ 그러나 콘텐츠 제공자는 기본적으로 다른 애플리케이션이 사용하도록 만들어진 것입니다.
+이들은 제공자 클라이언트 개체를 사용하여 제공자에 액세스합니다.
+제공자와 제공자 클라이언트가 결합되면 데이터에 하나의 일관적인 표준 인터페이스를 제공하여
+이것이 프로세스간 통신과 보안 데이터 액세스도 처리합니다.
+</p>
+<p>
+ 이 주제에서는 다음의 기본 정보를 설명합니다.
+</p>
+ <ul>
+ <li>콘텐츠 제공자의 작동 원리</li>
+ <li>콘텐츠 제공자에서 데이터를 검색할 때 사용하는 API</li>
+ <li>콘텐츠 제공자 내의 데이터를 삽입, 업데이트 및 삭제하는 데 사용하는 API</li>
+ <li>제공자를 다루는 데 도움이 되는 기타 API 기능</li>
+ </ul>
+
+ <!-- Basics -->
+<h2 id="Basics">개요</h2>
+<p>
+ 콘텐츠 제공자는 외부 애플리케이션에 데이터를 표시하며, 이때 데이터는
+관계형 데이터베이스에서 찾을 수 있는 테이블과 유사한 하나 이상의 테이블로서 표시됩니다.
+한 행은 제공자가 수집하는 어떤 유형의 데이터 인스턴스를 나타내며,
+행 안의 각 열은 인스턴스에 대해 수집된 개별적인 데이터를 나타냅니다.
+</p>
+<p>
+ 예를 들어 Android 플랫폼 안에 내장된 여러 제공자 중에 사용자 사전이라는 것이 있습니다.
+이것은 사용자가 보관하고 싶어하는 비표준 단어의 철자를 저장합니다. 표 1은 이 제공자의 테이블에서
+데이터가 어떤 형태를 띨 수 있는지를 나타낸 것입니다.
+</p>
+<p class="table-caption">
+ <strong>표 1:</strong> 샘플 사용자 사전 테이블입니다.
+</p>
+<table id="table1" style="width: 50%;">
+ <tr>
+ <th style="width:20%" align="center" scope="col">단어</th>
+ <th style="width:20%" align="center" scope="col">앱 ID</th>
+ <th style="width:20%" align="center" scope="col">빈도</th>
+ <th style="width:20%" align="center" scope="col">로케일</th>
+ <th style="width:20%" align="center" scope="col">_ID</th>
+ </tr>
+ <tr>
+ <td align="center" scope="row">mapreduce</td>
+ <td align="center">user1</td>
+ <td align="center">100</td>
+ <td align="center">en_US</td>
+ <td align="center">1</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">precompiler</td>
+ <td align="center">user14</td>
+ <td align="center">200</td>
+ <td align="center">fr_FR</td>
+ <td align="center">2</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">applet</td>
+ <td align="center">user2</td>
+ <td align="center">225</td>
+ <td align="center">fr_CA</td>
+ <td align="center">3</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">const</td>
+ <td align="center">user1</td>
+ <td align="center">255</td>
+ <td align="center">pt_BR</td>
+ <td align="center">4</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">int</td>
+ <td align="center">user5</td>
+ <td align="center">100</td>
+ <td align="center">en_UK</td>
+ <td align="center">5</td>
+ </tr>
+</table>
+<p>
+ 표 1에서, 각 행은 일반적인 사전에 나오지 않는 단어의 인스턴스를
+나타냅니다. 각 열은 해당 단어에 대한 일부 데이터를 나타냅니다. 예를 들어
+단어가 처음 나온 로케일 등을 들 수 있습니다. 열 헤더는 제공자에 저장된
+열 이름입니다. 행의 로케일을 참조하려면 그 행의 <code>locale</code> 열을 참조합니다.
+이 제공자의 경우, <code>_ID</code> 열은 제공자가 자동으로 유지하는 "기본 키" 열
+역할을 합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 제공자에 기본 키가 꼭 있어야 하는 것은 아니고,
+기본 키가 있는 경우 <code>_ID</code>를 열 이름으로 사용하지 않아도 됩니다. 그러나 제공자의 데이터를
+{@link android.widget.ListView}에 바인딩하려면
+열 이름 중 하나는<code>_ID</code>여야 합니다. 이 요구 사항은
+<a href="#DisplayResults">쿼리 결과 표시</a> 섹션에 자세히 설명되어 있습니다.
+</p>
+<h3 id="ClientProvider">제공자 액세스</h3>
+<p>
+ 애플리케이션은 콘텐츠 제공자로부터의 데이터에
+{@link android.content.ContentResolver} 클라이언트 개체로 액세스합니다.
+이 개체에는 제공자 개체 내의 같은 이름을 가진 메서드를 호출하는 메서드가 있습니다.
+이는 {@link android.content.ContentProvider}의 구체적인 하위 클래스 중 하나의 인스턴스입니다.
+{@link android.content.ContentResolver} 메서드는
+영구적 저장소의 기본적인 "CRUD"(생성, 검색, 업데이트 및 삭제) 기능을 제공합니다.
+</p>
+<p>
+ 클라이언트 애플리케이션의 프로세스 내에 있는 {@link android.content.ContentResolver} 개체와
+ 제공자를 소유하는 애플리케이션 내의 {@link android.content.ContentProvider} 개체가
+자동으로 프로세스간 통신을 처리합니다.
+{@link android.content.ContentProvider} 또한
+콘텐츠 제공자의 데이터 리포지토리와 외부에 테이블로 표시되는 데이터 모습 사이에서 추상화 계층 역할을 합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 제공자에 액세스하려면 보통은 애플리케이션이
+제공자의 매니페스트 파일에 있는 특정 권한을 요청해야 합니다. 이것은
+<a href="#Permissions">콘텐츠 제공자 권한</a> 섹션에 더 자세히 설명되어 있습니다.
+</p>
+<p>
+ 예를 들어 사용자 사전 제공자로부터 단어와 그에 해당하는 로케일 목록을 가져오려면,
+{@link android.content.ContentResolver#query ContentResolver.query()}를 호출하면 됩니다.
+ {@link android.content.ContentResolver#query query()} 메서드는 사용자 사전 제공자가 정의한
+{@link android.content.ContentProvider#query ContentProvider.query()} 메서드를
+호출합니다. 다음 몇 줄의 코드는
+{@link android.content.ContentResolver#query ContentResolver.query()} 호출을 나타낸 것입니다.
+<p>
+<pre>
+// Queries the user dictionary and returns results
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Selection criteria
+ mSelectionArgs, // Selection criteria
+ mSortOrder); // The sort order for the returned rows
+</pre>
+<p>
+ 표 2는
+{@link android.content.ContentResolver#query
+query(Uri,projection,selection,selectionArgs,sortOrder)}에 대한 인수가 SQL SELECT 문과 일치하는 방식을 나타낸 것입니다.
+</p>
+<p class="table-caption">
+ <strong>표 2:</strong> Query()를 SQL 쿼리에 비교한 것입니다.
+</p>
+<table id="table2" style="width: 75%;">
+ <tr>
+ <th style="width:25%" align="center" scope="col">query() 인수</th>
+ <th style="width:25%" align="center" scope="col">SELECT 키워드/매개변수</th>
+ <th style="width:50%" align="center" scope="col">참고</th>
+ </tr>
+ <tr>
+ <td align="center"><code>Uri</code></td>
+ <td align="center"><code>FROM <em>table_name</em></code></td>
+ <td><code>Uri</code>가 <em>table_name</em>이라 불리는 제공자에 있는 테이블에 매핑됩니다.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>projection</code></td>
+ <td align="center"><code><em>col,col,col,...</em></code></td>
+ <td>
+ <code>projection</code>은 검색된 각 행에 포함되어야 하는 일련의 열입니다.
+
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>selection</code></td>
+ <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td>
+ <td><code>selection</code>은 행을 선택하는 기준을 나타냅니다.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>selectionArgs</code></td>
+ <td align="center">
+ (정확한 등가는 없습니다. 선택 인수는 선택 절에 있는 <code>?</code>
+ 자리 표시자를 대체합니다.)
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>sortOrder</code></td>
+ <td align="center"><code>ORDER BY <em>col,col,...</em></code></td>
+ <td>
+ <code>sortOrder</code>는 반환된
+{@link android.database.Cursor} 내에 행이 나타나는 순서를 지정합니다.
+ </td>
+ </tr>
+</table>
+<h3 id="ContentURIs">콘텐츠 URI</h3>
+<p>
+ <strong>콘텐츠 URI</strong>는 제공자에서 데이터를 식별하는 URI입니다.
+콘텐츠 URI에는 전체 제공자의 상징적인 이름(제공자의 <strong>권한</strong>)과
+테이블을 가리키는 이름(<strong>경로</strong>)이 포함됩니다.
+제공자 내의 테이블에 액세스하기 위해 클라이언트 메서드를 호출하는 경우,
+그 테이블에 대한 콘텐츠 URI는 인수 중 하나입니다.
+</p>
+<p>
+ 앞선 몇 줄의 코드에서 상수
+{@link android.provider.UserDictionary.Words#CONTENT_URI}에
+사용자 사전의 "단어" 테이블의 콘텐츠 URI가 들어있습니다. {@link android.content.ContentResolver}
+ 개체가 이 URI의 권한을 구문 분석한 다음, 이를 이용해 제공자를 "확인"합니다. 즉 이 권한을 알려진 제공자로 이루어진 시스템 테이블과 비교하는 것입니다.
+
+그러면 {@link android.content.ContentResolver}가 쿼리 인수를
+올바른 제공자에게 발송할 수 있습니다.
+</p>
+<p>
+ {@link android.content.ContentProvider}는 콘텐츠 URI의 경로 부분을 사용하여
+액세스할 테이블을 선택합니다. 제공자에는 보통 제공자가 노출하는 테이블마다 <strong>경로</strong>가 있습니다.
+</p>
+<p>
+ 앞선 몇 줄의 코드에서 "단어" 테이블에 대한 전체 URI는 다음과 같습니다.
+</p>
+<pre>
+content://user_dictionary/words
+</pre>
+<p>
+ 여기에서 <code>user_dictionary</code> 문자열은 제공자의 권한이고
+<code>words</code> 문자열은 테이블의 경로입니다. 문자열
+<code>content://</code>(<strong>구성표</strong>)는 언제나 표시되며,
+이것을 콘텐츠 URI로 식별합니다.
+</p>
+<p>
+ 대다수의 제공자에서는 URI의 맨 끝에 ID 값을 추가하면
+테이블 내 하나의 행에 액세스할 수 있게 해줍니다. 예를 들어 <code>_ID</code>가
+사용자 사전의 <code>4</code>인 행을 검색하려면, 이 콘텐츠 URI를 사용하면 됩니다.
+</p>
+<pre>
+Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
+</pre>
+<p>
+ 일련의 행을 검색한 다음 그 중 하나를 업데이트하거나 삭제하고자 하는 경우 종종 ID 값을
+이용하곤 합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> {@link android.net.Uri}와
+{@link android.net.Uri.Builder} 클래스에는 문자열에서 잘 구성된(Well-Formed) URI 개체를 구성하기 위한 편의 메서드가 들어 있습니다.
+{@link android.content.ContentUris}에는 URI에 ID 값을 추가하기 위한 편의 메서드가 들어 있습니다.
+이전 조각은 {@link android.content.ContentUris#withAppendedId
+withAppendedId()}를 사용하여 UserDictionary 콘텐츠 URI에 ID를 추가합니다.
+</p>
+
+
+ <!-- Retrieving Data from the Provider -->
+<h2 id="SimpleQuery">제공자에서 데이터 검색</h2>
+<p>
+ 이 섹션은 사용자 사전 제공자를 예시로 사용하여 제공자에서 데이터를 검색하는
+방법을 설명합니다.
+</p>
+<p class="note">
+ 명확히 나타내기 위해 이 섹션의 코드 조각은
+{@link android.content.ContentResolver#query ContentResolver.query()}를 "UI 스레드"에서 호출합니다.
+그러나 실제 코드의 경우 쿼리는 별도의 스레드에서 비동기식으로 수행해야 합니다. 이를 위한 한 가지 방식으로
+{@link android.content.CursorLoader}
+클래스를 쓰는 것을 들 수 있습니다. 이 내용은 <a href="{@docRoot}guide/components/loaders.html">
+로더</a> 가이드에 더 자세히 설명되어 있습니다. 또한, 이 코드 줄은 조각일 뿐이며 애플리케이션을 전체적으로 표시한 것이 아닙니다.
+
+</p>
+<p>
+ 제공자에서 데이터를 검색하려면 다음과 같은 기본 단계를 따르십시오.
+</p>
+<ol>
+ <li>
+ 제공자에 대한 읽기 액세스 권한을 요청합니다.
+ </li>
+ <li>
+ 제공자에게 쿼리를 보내는 코드를 정의합니다.
+ </li>
+</ol>
+<h3 id="RequestPermissions">읽기 액세스 권한 요청</h3>
+<p>
+ 제공자에서 데이터를 검색하려면 애플리케이션에 해당 제공자에 대한 "읽기 액세스 권한"이 필요합니다.
+ 런타임에는 이 권한을 요청할 수 없습니다. 대신 이 권한이 필요하다는 것을 매니페스트에 나타내야 합니다. 이때,
+
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+ 요소와 제공자가 정의한 정확한 권한 이름을 사용하면 됩니다.
+ 매니페스트에서 이 요소를 지정하는 것은 사실상 애플리케이션을 위해 이 권한을 "요청"하는 것과
+같습니다. 사용자가 애플리케이션을 설치할 때면, 이 요청을 암시적으로 허용하게 됩니다.
+
+</p>
+<p>
+ 사용 중인 제공자에 대한 읽기 액세스 권한의 정확한 이름과 해당 제공자가 사용하는
+다른 액세스 권한의 이름을 찾아보려면 제공자의 문서를 살펴보십시오.
+
+</p>
+<p>
+ 제공자에 액세스하는 데 있어 권한이 어떤 역할을 하는지는
+<a href="#Permissions">콘텐츠 제공자 권한</a> 섹션에 더 자세하게 설명되어 있습니다.
+</p>
+<p>
+ 사용자 사전 제공자는
+<code>android.permission.READ_USER_DICTIONARY</code> 권한을 자신의 매니페스트 파일에 정의합니다. 따라서 해당 제공자에서
+읽기 작업을 하고자 하는 애플리케이션은 반드시 이 권한을 요청해야 합니다.
+</p>
+<!-- Constructing the query -->
+<h3 id="Query">쿼리 구성</h3>
+<p>
+ 제공자에서 데이터를 검색할 때 다음 단계는 쿼리를 구성하는 것입니다. 다음의 첫 번째 조각은
+사용자 사전 제공자에 액세스하는 데 필요한 몇 가지 변수를 정의한 것입니다.
+</p>
+<pre class="prettyprint">
+
+// A "projection" defines the columns that will be returned for each row
+String[] mProjection =
+{
+ UserDictionary.Words._ID, // Contract class constant for the _ID column name
+ UserDictionary.Words.WORD, // Contract class constant for the word column name
+ UserDictionary.Words.LOCALE // Contract class constant for the locale column name
+};
+
+// Defines a string to contain the selection clause
+String mSelectionClause = null;
+
+// Initializes an array to contain selection arguments
+String[] mSelectionArgs = {""};
+
+</pre>
+<p>
+ 다음 조각은 사용자 사전 제공자를 예시로 사용하여
+{@link android.content.ContentResolver#query ContentResolver.query()}를
+ 사용하는 방법을 나타낸 것입니다. 제공자 클라이언트 쿼리는 SQL 쿼리와 비슷하며,
+반환할 열 집합과 선택 기준 집합, 그리고 정렬 순서가 이 안에 들어 있습니다.
+</p>
+<p>
+ 쿼리가 반환해야 할 열 집합을 <strong>프로젝션</strong>
+(변수<code>mProjection</code>)이라고 합니다.
+</p>
+<p>
+ 검색할 행을 나타내는 식은 선택 절과 선택 인수로 분할되어 있습니다.
+ 선택 절은 논리와 부울 식, 열 이름과 값
+(변수 <code>mSelectionClause</code>)을 조합한 것입니다.
+값 대신 대체 가능한 매개변수 <code>?</code>를 지정하면,
+쿼리 메서드가 그 값을 선택 인수 배열에서 검색합니다(변수 <code>mSelectionArgs</code>).
+</p>
+<p>
+ 다음 조각의 경우, 사용자가 단어를 입력하지 않으면 선택 절이
+<code>null</code>로 설정되고, 쿼리는 제공자 안의 모든 단어를 반환합니다.
+사용자가 단어를 입력하면 선택 절은 <code>UserDictionary.Words.WORD + " = ?"</code>로 설정되며
+선택 인수의 첫 번째 요소가 사용자가 입력한 단어로 설정됩니다.
+</p>
+<pre class="prettyprint">
+/*
+ * This defines a one-element String array to contain the selection argument.
+ */
+String[] mSelectionArgs = {""};
+
+// Gets a word from the UI
+mSearchString = mSearchWord.getText().toString();
+
+// Remember to insert code here to check for invalid or malicious input.
+
+// If the word is the empty string, gets everything
+if (TextUtils.isEmpty(mSearchString)) {
+ // Setting the selection clause to null will return all words
+ mSelectionClause = null;
+ mSelectionArgs[0] = "";
+
+} else {
+ // Constructs a selection clause that matches the word that the user entered.
+ mSelectionClause = UserDictionary.Words.WORD + " = ?";
+
+ // Moves the user's input string to the selection arguments.
+ mSelectionArgs[0] = mSearchString;
+
+}
+
+// Does a query against the table and returns a Cursor object
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Either null, or the word the user entered
+ mSelectionArgs, // Either empty, or the string the user entered
+ mSortOrder); // The sort order for the returned rows
+
+// Some providers return null if an error occurs, others throw an exception
+if (null == mCursor) {
+ /*
+ * Insert code here to handle the error. Be sure not to use the cursor! You may want to
+ * call android.util.Log.e() to log this error.
+ *
+ */
+// If the Cursor is empty, the provider found no matches
+} else if (mCursor.getCount() &lt; 1) {
+
+ /*
+ * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
+ * an error. You may want to offer the user the option to insert a new row, or re-type the
+ * search term.
+ */
+
+} else {
+ // Insert code here to do something with the results
+
+}
+</pre>
+<p>
+ 이 쿼리는 SQL 문에 대한 아날로그입니다.
+</p>
+<pre>
+SELECT _ID, word, locale FROM words WHERE word = &lt;userinput&gt; ORDER BY word ASC;
+</pre>
+<p>
+ 이 SQL 문에서는 계약 클래스 상수 대신 실제 열 이름을 사용하였습니다.
+</p>
+<h4 id="Injection">악의적인 입력에 대한 보호</h4>
+<p>
+ 콘텐츠 제공자가 관리하는 데이터가 SQL 데이터베이스에 있는 경우,
+원시 SQL 문에 외부의 신뢰할 수 없는 데이터를 포함시키면 SQL 삽입을 초래할 수 있습니다.
+</p>
+<p>
+ 이 선택 절을 예로 들어 봅시다.
+</p>
+<pre>
+// Constructs a selection clause by concatenating the user's input to the column name
+String mSelectionClause = "var = " + mUserInput;
+</pre>
+<p>
+ 이렇게 하면 사용자로 하여금 여러분의 SQL 문에 악의적인 SQL을 연결할 수 있도록 허용합니다.
+ 예를 들어 사용자가 <code>mUserInput</code>에 대해 "nothing; DROP TABLE *;"을 입력할 수 있습니다.
+그러면 그 결과로 선택 절 <code>var = nothing; DROP TABLE *;</code>이 나옵니다.
+선택 절이 일종의 SQL 문으로 취급되었기 때문에 제공자가 기본 SQLite 데이터베이스에서 테이블을
+모두 삭제하는 결과를 낳을 수도 있습니다(제공자가 <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL 삽입</a>
+시도를 잡아내도록 설정된 경우는 예외입니다).
+</p>
+<p>
+ 이 문제를 피하려면 <code>?</code>를 대체 가능한 매개변수로 사용하는 선택 절과,
+별도의 선택 인수 배열을 사용하면 됩니다. 이렇게 하면, 사용자 입력이 SQL 문의 일부로 해석되기보다 쿼리에 직접 바인딩됩니다.
+
+ 이것은 SQL로 취급되지 않기 때문에 사용자 입력이 악의적인 SQL을 삽입할 수 없습니다.
+사용자 입력을 포함하는 데 연결을 사용하는 대신 다음 선택 절을 사용합니다.
+</p>
+<pre>
+// Constructs a selection clause with a replaceable parameter
+String mSelectionClause = "var = ?";
+</pre>
+<p>
+ 선택 인수 배열을 이렇게 설정합니다.
+</p>
+<pre>
+// Defines an array to contain the selection arguments
+String[] selectionArgs = {""};
+</pre>
+<p>
+ 선택 인수 배열에 값을 입력할 때는 이렇게 합니다.
+</p>
+<pre>
+// Sets the selection argument to the user's input
+selectionArgs[0] = mUserInput;
+</pre>
+<p>
+ <code>?</code>를 대체 가능한 매개변수로 사용하는 선택 절과
+선택 인수 배열을 사용하는 것이 선택을 지정하는 데 선호되는 방법입니다.
+이는 제공자가 SQL 데이터베이스 기반이 아닐 때에도 마찬가지입니다.
+</p>
+<!-- Displaying the results -->
+<h3 id="DisplayResults">쿼리 결과 표시</h3>
+<p>
+ {@link android.content.ContentResolver#query ContentResolver.query()}
+클라이언트 메서드는 언제나 쿼리 선택 기준과 일치하는 행에 대해 쿼리 프로젝션이 지정한 열을 포함하는
+{@link android.database.Cursor}를 반환합니다.
+{@link android.database.Cursor} 개체가 자신이 포함한 행과 열에 무작위 읽기 액세스를 제공합니다.
+ {@link android.database.Cursor} 메서드를 사용하면 행을 결과에서 반복할 수 있고,
+각 열의 데이터 유형을 결정하며 열에서 데이터를 꺼내거나 결과의 다른 속성을 검토할 수도 있습니다.
+ 일부 {@link android.database.Cursor} 구현은 제공자의 데이터가 변경될 경우,
+{@link android.database.Cursor}가 변경될 때 관찰자 개체 내의 메서드를 트리거하는 경우
+또는 두 가지가 한 번에 발생할 경우 자동으로 개체를 업데이트합니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 제공자는 쿼리를 수행하는 개체의 성격을 근거로
+열에 대한 액세스를 제한할 수 있습니다. 예를 들어 연락처 제공자는 동기화 어댑터로의 몇몇 열에 대한 액세스를 제한합니다.
+이렇게 해야 액티비티 또는 서비스에 열을 반환하지 않기 때문입니다.
+</p>
+<p>
+ 선택 기준에 일치하는 행이 없으면, 제공자는
+{@link android.database.Cursor} 개체를 반환합니다. 이 개체의
+{@link android.database.Cursor#getCount Cursor.getCount()}는 0(빈 커서)입니다.
+</p>
+<p>
+ 내부 오류가 발생하는 경우, 쿼리 결과는 특정 제공자에 따라 달라집니다.
+<code>null</code>을 반환하기로 선택할 수도 있고, {@link java.lang.Exception}을 발생시킬 수도 있습니다.
+</p>
+<p>
+ {@link android.database.Cursor}는 행의 "목록"이므로,
+{@link android.database.Cursor}의 콘텐츠를 표시하는 좋은 방법은 {@link android.widget.SimpleCursorAdapter}를 통해 {@link android.widget.ListView}에
+연결하는 것입니다.
+</p>
+<p>
+ 다음 조각은 이전 조각으로부터 코드를 계속 이어가는 것입니다.
+이는 해당 쿼리가 검색한 {@link android.database.Cursor}가 들어 있는
+{@link android.widget.SimpleCursorAdapter} 개체를 생성하며, 이 개체를
+{@link android.widget.ListView}에 대한 어댑터로 설정합니다.
+</p>
+<pre class="prettyprint">
+// Defines a list of columns to retrieve from the Cursor and load into an output row
+String[] mWordListColumns =
+{
+ UserDictionary.Words.WORD, // Contract class constant containing the word column name
+ UserDictionary.Words.LOCALE // Contract class constant containing the locale column name
+};
+
+// Defines a list of View IDs that will receive the Cursor columns for each row
+int[] mWordListItems = { R.id.dictWord, R.id.locale};
+
+// Creates a new SimpleCursorAdapter
+mCursorAdapter = new SimpleCursorAdapter(
+ getApplicationContext(), // The application's Context object
+ R.layout.wordlistrow, // A layout in XML for one row in the ListView
+ mCursor, // The result from the query
+ mWordListColumns, // A string array of column names in the cursor
+ mWordListItems, // An integer array of view IDs in the row layout
+ 0); // Flags (usually none are needed)
+
+// Sets the adapter for the ListView
+mWordList.setAdapter(mCursorAdapter);
+</pre>
+<p class="note">
+ <strong>참고:</strong> {@link android.database.Cursor}로 {@link android.widget.ListView}를 뒷받침하려면,
+커서에 <code>_ID</code>라는 열이 포함되어야 합니다.
+ 이것 때문에 이전에 표시된 쿼리가 "단어" 테이블에 대하여 <code>_ID</code> 열을
+검색하며, {@link android.widget.ListView}가 이를 표시하지 않더라도 무관합니다.
+ 이 제한은 대부분의 제공자에 각 테이블에 대한 <code>_ID</code> 열이 있는 이유를 설명해주기도 합니다.
+
+</p>
+
+ <!-- Getting data from query results -->
+<h3 id="GettingResults">쿼리 결과에서 데이터 가져오기</h3>
+<p>
+ 쿼리 결과를 단순히 표시만 하는 것보다 이를 다른 작업에 사용할 수 있습니다.
+예를 들어, 사용자 사전에서 철자를 검색한 다음 이것을 다른 제공자 내에서 찾아볼 수 있습니다.
+ 이렇게 하려면, {@link android.database.Cursor}에서 행을 계속 반복하면 됩니다.
+</p>
+<pre class="prettyprint">
+
+// Determine the column index of the column named "word"
+int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);
+
+/*
+ * Only executes if the cursor is valid. The User Dictionary Provider returns null if
+ * an internal error occurs. Other providers may throw an Exception instead of returning null.
+ */
+
+if (mCursor != null) {
+ /*
+ * Moves to the next row in the cursor. Before the first movement in the cursor, the
+ * "row pointer" is -1, and if you try to retrieve data at that position you will get an
+ * exception.
+ */
+ while (mCursor.moveToNext()) {
+
+ // Gets the value from the column.
+ newWord = mCursor.getString(index);
+
+ // Insert code here to process the retrieved word.
+
+ ...
+
+ // end of while loop
+ }
+} else {
+
+ // Insert code here to report an error if the cursor is null or the provider threw an exception.
+}
+</pre>
+<p>
+ {@link android.database.Cursor} 구현에는
+여러 개의 "가져오기" 메서드가 들어 있어 개체로부터 여러 가지 유형의 데이터를 검색합니다. 예를 들어 이전 조각에서는
+{@link android.database.Cursor#getString getString()}을 사용합니다.
+여기에는 해당 열의 데이터 유형을 나타내는 값을 반환하는
+{@link android.database.Cursor#getType getType()} 메서드도 있습니다.
+</p>
+
+
+ <!-- Requesting permissions -->
+<h2 id="Permissions">콘텐츠 제공자 권한</h2>
+<p>
+ 제공자의 애플리케이션은 해당 제공자의 데이터에 액세스하려면 다른 애플리케이션이 반드시 가지고 있어야 하는
+권한을 지정할 수 있습니다. 이와 같은 권한을 통해 사용자는 한 애플리케이션이 어느 데이터에 액세스하려 시도할지
+알 수 있습니다. 다른 애플리케이션은 제공자의 요구 사항을 근거로 해당 제공자에 액세스하기 위해 필요한
+권한을 요청합니다. 최종 사용자는 애플리케이션을 설치할 때 요청된 권한을 보게 됩니다.
+
+</p>
+<p>
+ 제공자의 애플리케이션이 아무 권한도 지정하지 않은 경우, 다른 애플리케이션은 해당 제공자의
+데이터에 액세스할 수 없습니다. 그러나 제공자의 애플리케이션 내에 있는 구성 요소는
+지정된 권한과 무관하게 항상 읽기 및 쓰기 액세스 권한을 모두 가지고 있습니다.
+</p>
+<p>
+ 이전에 언급한 것과 같이 사용자 사전 제공자에서 데이터를 검색하려면
+<code>android.permission.READ_USER_DICTIONARY</code> 권한이 필요합니다.
+ 이 제공자에게는 데이터 삽입, 업데이트 또는 삭제에 각각 별도의 <code>android.permission.WRITE_USER_DICTIONARY</code>
+권한이 있습니다.
+</p>
+<p>
+ 제공자에 액세스하는 데 필요한 권한을 얻으려면 애플리케이션은
+자신의 매니페스트 파일에 있는 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+으로 그러한 권한을 요청합니다. Android 패키지 관리자가 애플리케이션을 설치하는 경우,
+사용자는 애플리케이션이 요청하는 권한을 모두 승인해야 합니다. 사용자가 이를 모두 승인하면
+패키지 관리자가 설치를 계속하지만, 사용자가 이를 승인하지 않으면 패키지 관리자는 설치를 중단합니다.
+
+</p>
+<p>
+
+다음 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+ 요소는 사용자 사전 제공자에 읽기 액세스 권한을 요청하는 것입니다.
+</p>
+<pre>
+ &lt;uses-permission android:name="android.permission.READ_USER_DICTIONARY"&gt;
+</pre>
+<p>
+ 제공자 액세스 권한이 미치는 영향은
+<a href="{@docRoot}guide/topics/security/security.html">보안 및 권한</a> 가이드에 좀 더 자세히 설명되어 있습니다.
+</p>
+
+
+<!-- Inserting, Updating, and Deleting Data -->
+<h2 id="Modifications">데이터 삽입, 업데이트 및 삭제</h2>
+<p>
+ 제공자로부터 데이터를 검색하는 것과 같은 방식으로, 데이터를 수정할 때에도 제공자 클라이언트와 제공자의
+{@link android.content.ContentProvider} 사이의 상호작용을 사용합니다.
+ {@link android.content.ContentResolver}의 메서드를 호출하면서
+{@link android.content.ContentProvider}의 상응하는 메서드로 전달된 인수를 사용합니다.
+제공자와 제공자의 클라이언트가 보안과 프로세스간 통신을 자동으로 처리합니다.
+</p>
+<h3 id="Inserting">데이터 삽입</h3>
+<p>
+ 데이터를 제공자 안으로 삽입하려면,
+{@link android.content.ContentResolver#insert ContentResolver.insert()}
+ 메서드를 호출합니다. 이 메서드는 제공자에 새로운 행을 삽입하고 해당 열에 대한 콘텐츠 URI를 반환합니다.
+ 이 조각은 사용자 사전 제공자에 새 단어를 삽입하는 방법을 나타낸 것입니다.
+</p>
+<pre class="prettyprint">
+// Defines a new Uri object that receives the result of the insertion
+Uri mNewUri;
+
+...
+
+// Defines an object to contain the new values to insert
+ContentValues mNewValues = new ContentValues();
+
+/*
+ * Sets the values of each column and inserts the word. The arguments to the "put"
+ * method are "column name" and "value"
+ */
+mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
+mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
+mNewValues.put(UserDictionary.Words.WORD, "insert");
+mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
+
+mNewUri = getContentResolver().insert(
+ UserDictionary.Word.CONTENT_URI, // the user dictionary content URI
+ mNewValues // the values to insert
+);
+</pre>
+<p>
+ 새로운 행에 대한 데이터는 단일 행 커서와 형태가 유사한 단일 {@link android.content.ContentValues} 개체로
+이동합니다. 이 개체 내의 열은 모두 같은 데이터 유형을 가지지 않아도 됩니다.
+또한 아예 값을 지정하고 싶지 않은 경우라면 열을 <code>null</code>로 설정할 수 있습니다.
+이때 {@link android.content.ContentValues#putNull ContentValues.putNull()}을 사용하면 됩니다.
+</p>
+<p>
+ 조각은 <code>_ID</code> 열을 추가하지 않습니다. 이 열은 자동으로 유지관리되기 때문입니다.
+ 제공자는 추가된 모든 열마다 고유한 <code>_ID</code> 값을 할당합니다.
+ 제공자는 보통 이 값을 테이블의 기본 키로 사용합니다.
+</p>
+<p>
+ <code>newUri</code>에 반환된 콘텐츠 URI는 다음과 같은 형식으로 새로 추가된 행을 식별합니다.
+
+</p>
+<pre>
+content://user_dictionary/words/&lt;id_value&gt;
+</pre>
+<p>
+ <code>&lt;id_value&gt;</code>는 새로운 행에 대한 <code>_ID</code>의 콘텐츠입니다.
+ 대부분의 제공자는 이런 형태의 콘텐츠 URI를 자동으로 감지할 수 있으며, 그런 다음 해당 행에서 요청된 작업을 수행합니다.
+
+</p>
+<p>
+ 반환된 {@link android.net.Uri}에서 <code>_ID</code> 값을 가져오려면
+{@link android.content.ContentUris#parseId ContentUris.parseId()}를 호출합니다.
+</p>
+<h3 id="Updating">데이터 업데이트</h3>
+<p>
+ 행을 업데이트하려면 업데이트된 값과 함께 {@link android.content.ContentValues} 개체를 사용합니다.
+이때 값은 삽입할 때와 똑같고, 선택 기준은 쿼리할 때와 같습니다.
+ 사용하는 클라이언트 메서드는
+{@link android.content.ContentResolver#update ContentResolver.update()}입니다.
+값을 추가하는 것은 업데이트 중인 열에 대한 {@link android.content.ContentValues} 개체에만 하면 됩니다.
+열의 콘텐츠를 삭제하려면, 값을 <code>null</code>로 설정하십시오.
+</p>
+<p>
+ 다음 조각에서는 로케일이 언어 "en"인 행 모두를 로케일 <code>null</code>을 가지도록 변경합니다.
+ 반환 값이 업데이트된 행 수입니다.
+</p>
+<pre>
+// Defines an object to contain the updated values
+ContentValues mUpdateValues = new ContentValues();
+
+// Defines selection criteria for the rows you want to update
+String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?";
+String[] mSelectionArgs = {"en_%"};
+
+// Defines a variable to contain the number of updated rows
+int mRowsUpdated = 0;
+
+...
+
+/*
+ * Sets the updated value and updates the selected words.
+ */
+mUpdateValues.putNull(UserDictionary.Words.LOCALE);
+
+mRowsUpdated = getContentResolver().update(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mUpdateValues // the columns to update
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+
+{@link android.content.ContentResolver#update ContentResolver.update()}를 호출하는 경우에는 사용자 입력도 삭제해야 합니다. 이 내용에 관해 자세히 알아보려면
+<a href="#Injection">악의적인 입력에 대한 보호</a> 섹션을 읽어 보십시오.
+</p>
+<h3 id="Deleting">데이터 삭제</h3>
+<p>
+ 행을 삭제하는 것은 행 데이터를 검색하는 것과 비슷합니다. 즉, 삭제하고자 하는 행에 대한 선택 기준을 지정하면
+클라이언트 메서드가 삭제된 행 수를 반환하는 식입니다.
+ 다음 조각은 앱 ID가 "user"와 일치하는 행을 삭제합니다. 메서드가 삭제된 행 수를 반환합니다.
+
+</p>
+<pre>
+
+// Defines selection criteria for the rows you want to delete
+String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
+String[] mSelectionArgs = {"user"};
+
+// Defines a variable to contain the number of rows deleted
+int mRowsDeleted = 0;
+
+...
+
+// Deletes the words that match the selection criteria
+mRowsDeleted = getContentResolver().delete(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+ {@link android.content.ContentResolver#delete ContentResolver.delete()}를
+호출하는 경우에는 사용자 입력도 삭제해야 합니다. 이 내용에 관해 자세히 알아보려면
+<a href="#Injection">악의적인 입력에 대한 보호</a> 섹션을 읽어 보십시오.
+</p>
+<!-- Provider Data Types -->
+<h2 id="DataTypes">제공자 데이터 유형</h2>
+<p>
+ 콘텐츠 제공자는 아주 다양한 데이터 유형을 제공할 수 있습니다.
+사용자 사전 제공자는 텍스트만 제공하지만, 제공자는 다음과 같은 형식도 제공할 수 있습니다.
+</p>
+ <ul>
+ <li>
+ 정수
+ </li>
+ <li>
+ 긴 정수(Long)
+ </li>
+ <li>
+ 부동 소수점 수
+ </li>
+ <li>
+ 긴 부동 소수점 수(double)
+ </li>
+ </ul>
+<p>
+ 제공자가 종종 사용하는 또 다른 데이터 유형은 64KB 바이트 배열로 구현되는 BLOB(Binary Large OBject)입니다.
+ 이용 가능한 데이터 유형을 확인하려면
+{@link android.database.Cursor} 클래스 "가져오기" 메서드를 살펴보면 됩니다.
+</p>
+<p>
+ 제공자 내의 각 열에 대한 데이터 유형은 보통 자신의 문서에 목록으로 나열되어 있습니다.
+ 사용자 사전 제공자의 데이터 유형은 제공자의 계약 클래스
+{@link android.provider.UserDictionary.Words}의 참조 문서에 나열되어 있습니다(계약 클래스는
+<a href="#ContractClasses">계약 클래스</a> 섹션에 설명되어 있습니다).
+ @link android.database.Cursor#getType
+ Cursor.getType()}을 호출해서도 데이터 유형을 결정할 수 있습니다.
+</p>
+<p>
+ 제공자는 스스로 정의하는 각 콘텐츠 URI의 MIME 데이터 유형 정보도 유지관리합니다.
+MIME 유형 정보를 사용하면 애플리케이션이 제공자가 제공하는 데이터를 처리할 수 있을지 알아낼 수도 있고,
+MIME 유형을 근거로 처리 유형을 선택할 수도 있습니다.
+MIME 유형이 필요한 시점은 주로 복잡한 데이터 구조 또는 파일이 들어 있는 제공자를 다룰 때입니다.
+ 예를 들어 연락처 제공자 내의 {@link android.provider.ContactsContract.Data}
+ 테이블은 MIME 유형을 사용하여 각 행에 저장된 연락처 데이터의 유형에 레이블을 붙입니다.
+ 콘텐츠 URI에 상응하는 MIME 유형을 가져오려면
+{@link android.content.ContentResolver#getType ContentResolver.getType()}을 호출하십시오.
+</p>
+<p>
+ <a href="#MIMETypeReference">MIME 유형 참조</a> 섹션에서 표준 및 사용자 지정 MIME 유형의
+두 가지를 모두 설명하고 있습니다.
+</p>
+
+
+<!-- Alternative Forms of Provider Access -->
+<h2 id="AltForms">제공자 액세스의 대체 형식</h2>
+<p>
+ 애플리케이션 개발에 있어 중요한 제공자 액세스의 대체 형식에는 다음과 같은 세 가지가 있습니다.
+</p>
+<ul>
+ <li>
+ <a href="#Batch">일괄 액세스</a>: {@link android.content.ContentProviderOperation}
+ 클래스에 있는 메서드로 일괄 액세스 호출을 생성하고
+{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}로 이를 적용할 수 있습니다.
+ </li>
+ <li>
+ 비동기식 쿼리: 쿼리는 별도의 스레드에서 수행해야 합니다. 이 작업을 수행하는 한 가지 방법으로
+{@link android.content.CursorLoader} 개체를 사용하는 것이 있습니다. 이 사용 방법은
+<a href="{@docRoot}guide/components/loaders.html">로더</a> 가이드에 있는 예시에서 설명합니다.
+
+ </li>
+ <li>
+ <a href="#Intents">인텐트를 통한 데이터 액세스</a>:
+인텐트를 제공자에 직접 보낼 수는 없지만, 인텐트를 제공자의 애플리케이션에 보낼 수는 있습니다.
+보통은 이것이 제공자의 데이터를 수정하기에 가장 좋습니다.
+ </li>
+</ul>
+<p>
+ 일괄 액세스와 인텐트를 통한 수정은 다음 섹션에서 설명되어 있습니다.
+</p>
+<h3 id="Batch">일괄 액세스</h3>
+<p>
+ 제공자에 일괄 액세스를 하면 많은 수의 행을 삽입할 때, 같은 메서드 호출 내에서 여러 개의 테이블에 여러 행을 삽입할 때
+또는 전반적으로, 프로세스 경계를 가로질러 일련의 작업을 수행하는 경우(원자성 작업) 유용합니다.
+
+</p>
+<p>
+ "일괄 모드"로 제공자에 액세스하려면
+{@link android.content.ContentProviderOperation} 개체의 배열을 생성한 다음 이를 콘텐츠 제공자에게
+{@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}로
+ 발송하면 됩니다.
+이 메서드에는 특정한 콘텐츠 URI보다는 콘텐츠 제공자의 <em>권한</em>을 전달합니다.
+이렇게 하면 배열 내의 각 {@link android.content.ContentProviderOperation} 개체가
+서로 다른 테이블에 대해 작용하도록 할 수 있습니다. {@link android.content.ContentResolver#applyBatch
+ ContentResolver.applyBatch()}를 호출하면 일련의 결과를 반환합니다.
+</p>
+<p>
+ {@link android.provider.ContactsContract.RawContacts} 계약 클래스의 설명에
+ 일괄 삽입을 설명하는 코드 조각이 포함되어 있습니다.
+<a href="{@docRoot}resources/samples/ContactManager/index.html">연락처 관리자</a>
+샘플 애플리케이션에는 <code>ContactAdder.java</code>
+소스 파일의 일괄 액세스 예시가 포함되어 있습니다.
+</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>도우미 앱을 사용한 데이터 표시</h2>
+<p>
+ 애플리케이션에 액세스 권한이 <em>있더라도</em>
+다른 애플리케이션에 데이터를 표시할 인텐트를 사용하고자 할 수 있습니다. 예를 들어 캘린더 애플리케이션은
+특정 날짜나 이벤트를 표시하는 {@link android.content.Intent#ACTION_VIEW}를 허용합니다.
+ 이 때문에 나름의 UI를 직접 생성하지 않고도 캘린더 정보를 표시할 수 있습니다.
+이 기능에 대한 자세한 정보는
+<a href="{@docRoot}guide/topics/providers/calendar-provider.html">캘린더 제공자</a> 가이드를 참조하십시오.
+</p>
+<p>
+ 인텐트를 보낼 목적지인 애플리케이션은 제공자와 연관된 애플리케이션이 아니어도 됩니다.
+ 예를 들어 연락처 제공자에서 연락처를 검색한 다음, 해당 연락처의 이미지에 대한 콘텐츠 URI가 들어 있는
+{@link android.content.Intent#ACTION_VIEW} 인텐트를
+이미지 뷰어로 보낼 수 있습니다.
+</p>
+</div>
+</div>
+<h3 id="Intents">인텐트를 통한 데이터 액세스</h3>
+<p>
+ 인텐트는 콘텐츠 제공자에 간접 액세스를 제공할 수 있습니다. 애플리케이션에 액세스 권한이 없는데도
+사용자에게 제공자 내의 데이터에 액세스 권한을 허가하려면, 권한을 가지고 있는 애플리케이션에서 결과 인텐트를 다시 가져오거나
+권한이 있는 애플리케이션을 활성화한 다음 사용자에게 그 애플리케이션에서 작업하도록 하면 됩니다.
+
+</p>
+<h4>임시 권한으로 액세스 얻기</h4>
+<p>
+ 적절한 액세스 권한이 없더라도 콘텐츠 제공자 내의 데이터에 액세스할 수는 있습니다.
+권한을 가지고 있는 애플리케이션에 인텐트를 보내 "URI" 권한이 들어 있는 결과 인텐트를 돌려받으면 됩니다.
+
+ 이들 권한은 특정 콘텐츠 URI에 대한 권한으로, 이를 수신하는 액티비티가 완료될 때까지 유지됩니다.
+ 영구 권한을 가지고 있는 애플리케이션은 결과 인텐트에 다음과 같이 플래그를 설정하여 임시 권한을 허가합니다.
+
+</p>
+<ul>
+ <li>
+ <strong>읽기 권한:</strong>
+{@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
+ </li>
+ <li>
+ <strong>쓰기 권한:</strong>
+{@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}
+ </li>
+</ul>
+<p class="note">
+ <strong>참고:</strong> 이와 같은 플래그는 콘텐츠 URI에 권한이 들어 있는 제공자에 일반적인 읽기 또는 쓰기 액세스
+권한을 부여하지는 않습니다. 이 액세스는 URI 자체에만 해당됩니다.
+</p>
+<p>
+ 제공자는 자신의 매니페스트 내의 콘텐츠 URI에 대한 URI 권한을 정의합니다. 이때
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+ 요소의
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">android:grantUriPermission</a></code>
+ 속성을 사용하며,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+ 요소의
+<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+ 하위 요소도 사용합니다.
+URI 권한 메커니즘은 "URI 권한" 섹션의 <a href="{@docRoot}guide/topics/security/security.html">보안 및 권한</a> 가이드에
+자세히 설명되어 있습니다.
+</p>
+<p>
+ 예를 들어, {@link android.Manifest.permission#READ_CONTACTS} 권한이 없더라도
+연락처 제공자 내의 연락처에 대한 데이터를 검색할 수 있습니다.
+이 작업을 하면 좋은 예로, 연락처에 기재된 사람의 생일에 전자 축하 카드를 보내주는 애플리케이션을 들 수 있습니다.
+{@link android.Manifest.permission#READ_CONTACTS}를 요청하면
+사용자의 연락처 전체와 해당 정보 일체에 대한 액세스를 부여하므로, 그 대신 애플리케이션에서 어느 연락처를 사용할지 사용자가 직접 제어하도록 해주는 편이 낫습니다.
+ 이렇게 하려면, 다음 절차를 사용합니다.
+</p>
+<ol>
+ <li>
+ 애플리케이션이{@link android.app.Activity#startActivityForResult
+startActivityForResult()} 메서드를 사용해서
+{@link android.content.Intent#ACTION_PICK} 작업과 "contacts" MIME 유형
+{@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE}이 들어 있는 인텐트를 보냅니다.
+
+ </li>
+ <li>
+ 이 인텐트는 피플 앱의 "선택" 액티비티에 대한 인텐트 필터와 일치하기 때문에, 이 액티비티가 전경으로 나옵니다.
+
+ </li>
+ <li>
+ 선택 액티비티에서 사용자가 업데이트할 연락처를 선택합니다.
+ 이렇게 되면 선택 액티비티가
+{@link android.app.Activity#setResult setResult(resultcode, intent)}
+를 호출하여 애플리케이션에 돌려줄 인텐트를 설정합니다.
+이 인텐트에 사용자가 선택한 연락처의 콘텐츠 URI와 "추가" 플래그
+{@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}이 들어 있습니다.
+이러한 플래그가 URI에 앱으로의 권한을 허가하여 콘텐츠 URI가 가리킨 연락처에 대한 데이터를 읽을 수 있도록 합니다.
+그런 다음 선택 액티비티는 {@link android.app.Activity#finish()}를 호출하여
+애플리케이션에 제어를 반환합니다.
+ </li>
+ <li>
+ 액티비티가 전경으로 돌아오고, 시스템은 액티비티의
+{@link android.app.Activity#onActivityResult onActivityResult()} 메서드를
+호출합니다. 이 메서드가 피플 앱의 선택 액티비티가 생성한 결과 인텐트를 수신합니다.
+
+ </li>
+ <li>
+ 결과 인텐트로부터 받은 콘텐츠 URI를 사용하면 연락처 제공자에서 연락처의 데이터를 읽을 수 있습니다.
+이것은 매니페스트에서 제공자로의 영구 읽기 액세스 권한을 요청하지 않았어도 적용됩니다.
+ 그러면 연락처의 생일 정보나 당사자의 이메일 주소를 가져와 전자 축하 카드를 보낼 수 있게 됩니다.
+
+ </li>
+</ol>
+<h4>다른 애플리케이션 사용</h4>
+<p>
+ 개발자에게 액세스 권한이 없는 데이터를 사용자가 수정할 수 있도록 허용하는 간단한 방법은
+해당 권한을 가지고 있는 애플리케이션을 활성화한 다음 사용자에게 그곳에서 작업하도록 해주는 것입니다.
+</p>
+<p>
+ 예를 들어, 캘린더 애플리케이션은
+애플리케이션의 삽입 UI를 활성화해주는 {@link android.content.Intent#ACTION_INSERT} 인텐트를 수락합니다. 애플리케이션이 UI를 미리 채우는 데 사용하는 이 인텐트의 "extras" 데이터를
+전달할 수 있게 됩니다. 반복적인 이벤트의 구문은 복잡하므로
+캘린더 제공자에 이벤트를 삽입하기 좋은 방법은
+{@link android.content.Intent#ACTION_INSERT}로 캘린더 앱을 활성화하고 사용자에게 그곳에서 이벤트를
+삽입하게 하는 것입니다.
+</p>
+<!-- Contract Classes -->
+<h2 id="ContractClasses">계약 클래스</h2>
+<p>
+ 계약 클래스는 애플리케이션이 콘텐츠 URI, 열 이름, 인텐트 작업 및 콘텐츠 제공자의 다른 기능과
+작업할 수 있게 도와주는 상수를 정의합니다. 계약 클래스는 제공자와 함께 자동으로 포함되지 않습니다.
+해당 제공자의 개발자가 이를 정의한 다음 다른 개발자가 사용할 수 있도록 해야 합니다.
+ Android 플랫폼 내에 포함된 제공자는 대부분 패키지
+{@link android.provider} 안에 상응하는 계약 클래스를 가지고 있습니다.
+</p>
+<p>
+ 예를 들어, 사용자 사전 제공자에는 콘텐츠 URI와 열 이름 상수가 들어 있는
+{@link android.provider.UserDictionary} 계약 클래스가 있습니다.
+"단어" 테이블에 대한 콘텐츠 URI는 상수
+{@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI}에 정의됩니다.
+ {@link android.provider.UserDictionary.Words} 클래스에도
+열 이름 상수가 들어 있으며, 이는 이 가이드의 예시 조각에서 사용됩니다.
+예를 들어 쿼리 프로젝션은 다음과 같이 정의될 수 있습니다.
+</p>
+<pre>
+String[] mProjection =
+{
+ UserDictionary.Words._ID,
+ UserDictionary.Words.WORD,
+ UserDictionary.Words.LOCALE
+};
+</pre>
+<p>
+ 또 다른 계약 클래스는 연락처 제공자의 {@link android.provider.ContactsContract}입니다.
+ 이 클래스에 대한 참조 문서에는 예시 코드 조각이 포함되어 있습니다.
+이것의 하위 클래스 중 하나인 {@link android.provider.ContactsContract.Intents.Insert}는
+ 인텐트와 인텐트 데이터의 상수가 들어 있는 계약 클래스입니다.
+</p>
+
+
+<!-- MIME Type Reference -->
+<h2 id="MIMETypeReference">MIME 유형 참조</h2>
+<p>
+ 콘텐츠 제공자는 표준 MIME 미디어 유형이나 사용자 지정 MIME 유형 문자열, 또는 그 두 가지를 모두 반환할 수 있습니다.
+</p>
+<p>
+ MIME 유형의 형식은 다음과 같습니다.
+</p>
+<pre>
+<em>type</em>/<em>subtype</em>
+</pre>
+<p>
+ 예를 들어, 잘 알려진 MIME 유형 <code>text/html</code>에는 <code>text</code> 유형과
+<code>html</code> 하위 유형이 있습니다. 제공자가 URI에 대해 이 유형을 반환하면,
+해당 URI를 사용하는 쿼리가 HTML 태그가 들어 있는 텍스트를 반환할 것이라는 뜻입니다.
+</p>
+<p>
+ 사용자 지정 MIME 유형 문자열은 "공급업체별" MIME 유형이라고도 불리며
+이쪽의 <em>유형</em>과 <em>하위 유형</em> 값이 더 복잡합니다. <em>유형</em> 값은 경우에 따라 항상 다음과 같습니다.
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>
+</pre>
+<p>
+ (여러 행의 경우)
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>
+</pre>
+<p>
+ (하나의 행의 경우).
+</p>
+<p>
+ <em>하위 유형</em>은 제공자별로 다릅니다. Android 내장 제공자는 보통 단순한 하위 유형을 가지고 있습니다.
+ 예를 들어 연락처 애플리케이션이 전화 번호에 대한 행을 생성한다고 합니다. 이때 애플리케이션은 해당 행에 다음과 같은 MIME 유형을 설정하게 됩니다.
+
+</p>
+<pre>
+vnd.android.cursor.item/phone_v2
+</pre>
+<p>
+ 하위 유형 값은 단순히 <code>phone_v2</code>인 것을 눈여겨 보십시오.
+</p>
+<p>
+ 다른 제공자 개발자도 해당 제공자의 권한과 테이블 이름을 근거로 나름의 하위 유형 패턴을 만들 수 있습니다.
+ 예를 들어 기차 시간표가 들어 있는 제공자가 있다고 생각해 보겠습니다.
+ 제공자의 권한은 <code>com.example.trains</code>이고 이 안에 테이블
+Line1, Line2, Line3이 들어 있습니다. 다음과 같은 콘텐츠 URI에 대응하는 방식을 살펴보십시오.
+</p>
+<p>
+<pre>
+content://com.example.trains/Line1
+</pre>
+<p>
+ 테이블 Line1의 경우, 제공자는 다음과 같은 MIME 유형을 반환합니다.
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.example.line1
+</pre>
+<p>
+ 다음과 같은 콘텐츠 URI에 대응하는 방식을 살펴보십시오.
+</p>
+<pre>
+content://com.example.trains/Line2/5
+</pre>
+<p>
+ 테이블 Line2의 행 5에 대해 제공자가 반환하는 MIME 유형은 다음과 같습니다.
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.example.line2
+</pre>
+<p>
+ 대부분의 콘텐츠 제공자는 자신이 사용하는 MIME 유형에 대한 계약 클래스 상수를 정의합니다.
+예를 들어, 연락처 제공자 계약 클래스 {@link android.provider.ContactsContract.RawContacts}는
+단일 연락처 행의 MIME 유행에 대한
+ 상수 {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE}을
+정의합니다.
+</p>
+<p>
+ 한 행에 대한 콘텐츠 URI는
+<a href="#ContentURIs">콘텐츠 URI</a> 섹션에 설명되어 있습니다.
+</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/content-provider-creating.jd b/docs/html-intl/intl/ko/guide/topics/providers/content-provider-creating.jd
new file mode 100644
index 000000000000..6757194a9f28
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/content-provider-creating.jd
@@ -0,0 +1,1214 @@
+page.title= 콘텐츠 제공자 생성
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<h2>이 문서의 내용</h2>
+<ol>
+ <li>
+ <a href="#DataStorage">데이터 저장소 설계</a>
+ </li>
+ <li>
+ <a href="#ContentURI">콘텐츠 URI 설계</a>
+ </li>
+ <li>
+ <a href="#ContentProvider">ContentProvider 클래스 구현</a>
+ <ol>
+ <li>
+ <a href="#RequiredAccess">필수 메서드</a>
+ </li>
+ <li>
+ <a href="#Query">query() 메서드 구현</a>
+ </li>
+ <li>
+ <a href="#Insert">insert() 메서드 구현</a>
+ </li>
+ <li>
+ <a href="#Delete">delete() 메서드 구현</a>
+ </li>
+ <li>
+ <a href="#Update">update() 메서드 구현</a>
+ </li>
+ <li>
+ <a href="#OnCreate">onCreate() 메서드 구현</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#MIMETypes">콘텐츠 제공자 MIME 유형 구현</a>
+ <ol>
+ <li>
+ <a href="#TableMIMETypes">테이블의 MIME 유형</a>
+ </li>
+ <li>
+ <a href="#FileMIMETypes">파일의 MIME 유형</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClass">계약 클래스 구현</a>
+ </li>
+ <li>
+ <a href="#Permissions">콘텐츠 제공자 권한 구현</a>
+ </li>
+ <li>
+ <a href="#ProviderElement">&lt;provider&gt; 요소</a>
+ </li>
+ <li>
+ <a href="#Intents">인텐트 및 데이터 액세스</a>
+ </li>
+</ol>
+<h2>Key 클래스</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+<h2>관련 샘플</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/NotePad/index.html">
+ 메모장 샘플 애플리케이션
+ </a>
+ </li>
+ </ol>
+<h2>참고 항목</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ 콘텐츠 제공자 기본 정보</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ 캘린더 제공자</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+
+<p>
+ 콘텐츠 제공자는 데이터의 중앙 리포지토리로의 액세스를 관리합니다. Android 애플리케이션에서는
+제공자를 하나 이상의 클래스로, 매니페스트 파일에 있는 요소와 함께 구현합니다.
+ 클래스 중 하나가 하위 클래스
+{@link android.content.ContentProvider}를 구현하며,
+이것이 제공자와 다른 애플리케이션 사이의 인터페이스입니다. 콘텐츠 제공자는 다른 애플리케이션에 데이터를 사용할 수 있게 해주도록 만들어져 있지만,
+물론 애플리케이션 내에 사용자로 하여금 제공자가 관리하는 데이터를 쿼리하고 수정할 수 있게 허용하는
+액티비티가 있을 수도 있습니다.
+</p>
+<p>
+ 이 주제의 나머지 부분은 콘텐츠 제공자를 구축하기 위한 기본 단계 목록과
+사용할 API 목록으로 이루어져 있습니다.
+</p>
+
+
+<!-- Before You Start Building -->
+<h2 id="BeforeYouStart">구축을 시작하기 전에</h2>
+<p>
+ 제공자 구축을 시작하기 전에 우선 다음 단계를 수행하십시오.
+</p>
+<ol>
+ <li>
+ <strong>콘텐츠 제공자가 필요한지 결정합니다</strong>. 다음 기능 중 하나 이상을 제공하려면
+콘텐츠 제공자를 구축해야 합니다.
+ <ul>
+ <li>다른 애플리케이션에 복잡한 데이터나 파일을 제공하고자 하는 경우</li>
+ <li>사용자로 하여금 개발자의 앱에서 다른 앱으로 복잡한 데이터를 복사하도록 허용하고자 하는 경우</li>
+ <li>검색 프레임워크를 사용한 사용자 지정 검색 제안을 제공하고자 하는 경우</li>
+ </ul>
+ <p>
+ 용도가 본인의 애플리케이션 안에서로 완전히 한정되어 있는 경우에는
+제공자가 SQLite 데이터베이스를 사용하도록 하지 <em>않아도</em> 됩니다.
+ </p>
+ </li>
+ <li>
+ 아직 읽지 않았다면, 지금 바로
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+콘텐츠 제공자 기본 정보</a>를 읽고 제공자에 대해 자세히 알아보십시오.
+ </li>
+</ol>
+<p>
+ 그런 다음, 다음 단계를 따라 제공자를 구축합니다.
+</p>
+<ol>
+ <li>
+ 데이터를 위한 원시 저장소를 설계합니다. 콘텐츠 제공자는 두 가지 방식으로 데이터를 제공합니다.
+ <dl>
+ <dt>
+ 파일 데이터
+ </dt>
+ <dd>
+ 일반적으로 사진, 오디오 또는 동영상과 같은
+파일에 들어가는 데이터입니다. 이런 파일을 애플리케이션의 비공개
+공간에 저장합니다. 제공자는 다른 애플리케이션으로부터 온 파일 요청에 응답하여
+해당 파일로의 핸들을 제공할 수 있습니다.
+ </dd>
+ <dt>
+ "구조적" 데이터
+ </dt>
+ <dd>
+ 일반적으로 데이터베이스, 배열 또는 유사 구조에 들어가는 데이터입니다.
+ 이 데이터를 행과 열로 이루어진 테이블과 호환되는 형식으로 저장합니다.
+행은 사람이나 인벤토리의 항목과 같은 엔티티를 나타냅니다.
+열은 해당 엔티티에 대한 몇 가지 데이터, 예를 들어 사람 이름이나 항목 가격 등을 나타냅니다.
+이 유형의 데이터를 저장하는 보편적인 방법은 SQLite 데이터베이스 안에 저장하는 것이지만,
+모든 유형의 영구적인 저장소를 사용해도 됩니다. Android 시스템에서 사용할 수 있는 저장소 유형에 대해 자세히 알아보려면,
+<a href="#DataStorage">
+데이터 저장소 설계</a> 섹션을 참조하십시오.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ {@link android.content.ContentProvider} 클래스와
+필수 메서드의 구체적인 구현을 정의합니다. 이 클래스는 데이터와 나머지 Android 시스템 사이의
+인터페이스입니다. 이 클래스에 관한 자세한 정보는
+<a href="#ContentProvider">ContentProvider 클래스 구현</a> 섹션을 참조하십시오.
+ </li>
+ <li>
+ 제공자의 권한 문자열, 그 콘텐츠 URI 및 열 이름을 정의합니다.
+제공자 애플리케이션이 인텐트를 처리하게 하려면, 인텐트 작업과 추가 데이터 및
+플래그도 정의합니다. 데이터에 액세스하기를 원하는 애플리케이션에 요구할 권한도
+정의합니다. 이 모든 값은 별도의 계약 클래스에서 상수로 정의하는 것을 고려해보는
+것이 좋습니다. 이 클래스를 나중에 다른 개발자에게 노출할 수 있습니다.
+콘텐츠 URI에 관한 자세한 정보는
+<a href="#ContentURI">콘텐츠 URI 설계</a> 섹션을 참조하십시오.
+ 인텐트에 관한 자세한 정보는
+<a href="#Intents">인텐트 및 데이터 액세스</a> 섹션을 참조하십시오.
+ </li>
+ <li>
+ 샘플 데이터, 또는 제공자와 클라우드 기반 데이터 사이에서
+데이터를 동기화할 수 있는 {@link android.content.AbstractThreadedSyncAdapter} 구현 등과 같이
+다른 선택적 조각을 추가합니다.
+ </li>
+</ol>
+
+
+<!-- Designing Data Storage -->
+<h2 id="DataStorage">데이터 저장소 설계</h2>
+<p>
+ 콘텐츠 제공자는 구조화된 형식으로 저장된 데이터로의 인터페이스입니다.
+인터페이스를 생성하기 전에 우선 데이터 저장 방식부터 결정해야 합니다.
+데이터는 원하는 형식 아무 것으로나 저장할 수 있으며 그런 다음에 필요에 따라 해당 데이터를 읽고 쓸 인터페이스를 설계합니다.
+</p>
+<p>
+ 다음은 Android에서 사용할 수 있는 몇 가지 데이터 저장소 기술입니다.
+</p>
+<ul>
+ <li>
+ Android 시스템에는 Android 자체 제공자가 테이블 지향적 데이터를
+저장하는 데 사용하는 SQLite 데이터베이스 API가 포함됩니다.
+{@link android.database.sqlite.SQLiteOpenHelper} 클래스는 데이터베이스를 생성할 수 있게 돕고,
+{@link android.database.sqlite.SQLiteDatabase} 클래스는 데이터베이스 액세스를 위한
+기본 클래스입니다.
+ <p>
+ 리포지토리를 구현하기 위해 데이터베이스를 사용하지 않아도 된다는 점을 기억하십시오.
+제공자는 외부에 테이블 집합으로 나타나 관계적 데이터베이스와 비슷해 보이지만,
+이것은 제공자의 내부 구현에 필요한 것은 아닙니다.
+ </p>
+ </li>
+ <li>
+ 파일 데이터를 저장하는 데 있어 Android에는 다양한 파일 지향적 API가 있습니다.
+ 파일 저장소에 관해 자세히 알아보려면
+<a href="{@docRoot}guide/topics/data/data-storage.html">데이터 저장소</a> 주제를 읽어 보십시오.
+음악이나 동영상 등 미디어 관련 데이터를 제공하는 제공자를 설계하는 경우,
+제공자가 테이블 데이터와 파일을 조합 할 수 있습니다.
+ </li>
+ <li>
+ 네트워크 기반 데이터를 다루는 경우, {@link java.net} 및
+{@link android.net} 내의 클래스를 사용하십시오. 네트워크 기반 데이터를
+데이터베이스와 같은 로컬 데이터 스토어와 동기화한 다음, 해당 데이터를 테이블이나 파일로 제공할 수도 있습니다.
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+샘플 동기화 어댑터</a> 샘플 애플리케이션이 이런 유형의 동기화를 보여줍니다.
+ </li>
+</ul>
+<h3 id="DataDesign">
+ 데이터 설계 시 고려할 사항
+</h3>
+<p>
+ 다음은 제공자의 데이터 구조를 설계할 때 유용한 몇 가지 팁입니다.
+</p>
+<ul>
+ <li>
+ 테이블 데이터는 언제나 제공자가 유지관리하는 "기본 키" 열을
+각 행의 고유한 숫자 값으로 보유하고 있어야 합니다. 이 값을 사용하여 해당 행을 다른 테이블의
+관련 행에 연결시킬 수 있습니다(이를 "외래 키"로 사용). 이 열에는 어느 이름이든 사용할 수 있지만
+{@link android.provider.BaseColumns#_ID BaseColumns._ID}를 사용하는 것이 가장 좋습니다.
+왜냐하면 제공자 쿼리 결과를
+{@link android.widget.ListView}에 연결하려면 검색된 열 중 하나가
+<code>_ID</code>라는 이름을 사용해야 하기 때문입니다.
+ </li>
+ <li>
+ 비트맵 이미지나 파일 지향적 데이터의 매우 큰 조각을 제공하려면
+테이블 안에 직접 저장하기보다는 파일에 데이터를 저장한 뒤
+간접적으로 제공합니다. 이렇게 하는 경우, 제공자의 사용자들에게 데이터에 액세스하려면
+{@link android.content.ContentResolver} 파일 메서드를 사용해야 한다고 알려야 합니다.
+ </li>
+ <li>
+ BLOB(Binary Large OBject) 데이터 유형을 사용하여 크기가 다르거나
+구조가 다양한 데이터를 저장합니다. 예를 들어, BLOB 열을 사용하여
+<a href="http://code.google.com/p/protobuf">프로토콜 버퍼</a> 또는
+<a href="http://www.json.org">JSON 구조</a>를 저장할 수 있습니다.
+ <p>
+ BLOB를 사용하여 <em>스키마에 종속되지 않은</em> 테이블을 구현할 수도 있습니다.
+이 유형의 테이블에서는, 기본 키 열, MIME 유형 열 및 하나 이상의 일반적인 열을 BLOB로 정의합니다.
+
+BLOB 열에 있는 데이터의 의미는 MIME 유형 열에 있는 값으로 나타냅니다.
+이렇게 하면 같은 테이블에 여러 가지 행 유형을 저장할 수 있습니다. 연락처 제공자의 "데이터" 테이블
+{@link android.provider.ContactsContract.Data}가
+스키마에 종속되지 않은 테이블의 한 가지 예입니다.
+ </p>
+ </li>
+</ul>
+<!-- Designing Content URIs -->
+<h2 id="ContentURI">콘텐츠 URI 설계</h2>
+<p>
+ <strong>콘텐츠 URI</strong>는 제공자에서 데이터를 식별하는 URI입니다.
+콘텐츠 URI에는 전체 제공자의 상징적인 이름(제공자의 <strong>권한</strong>)과
+테이블 또는 파일을 가리키는 이름(<strong>경로</strong>)이 포함됩니다.
+선택 항목 ID 부분은 테이블 내의 개별적인 행을 가리킵니다.
+{@link android.content.ContentProvider}의 모든 데이터 액세스 메서드는
+콘텐츠 URI를 인수로 가집니다. 이를 통해 액세스할 테이블, 행 또는 파일을 결정할 수 있습니다.
+</p>
+<p>
+ 콘텐츠 URI의 기본 정보는
+<a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+콘텐츠 제공자 기본 정보</a>에 설명되어 있습니다.
+</p>
+<h3>권한 설계</h3>
+<p>
+ 제공자에는 보통 하나의 권한이 있으며, 이것이 Android 내부 이름 역할을 합니다.
+다른 제공자와의 충돌을 피하려면, 제공자 권한의 기반으로 인터넷 도메인 소유권(역방향)을
+사용해야 합니다. 이 권장 사항은 Android 패키지 이름에도 적용되므로,
+제공자 권한을 제공자가 들어 있는 패키지의 이름 확장자로 정의해도 됩니다.
+ 예를 들어, Android 패키지 이름이
+<code>com.example.&lt;appname&gt;</code>라면, 제공자에게
+<code>com.example.&lt;appname&gt;.provider</code> 권한을 부여해야 합니다.
+</p>
+<h3>경로 구조 설계</h3>
+<p>
+ 개발자는 보통 권한으로부터 콘텐츠 URI를 생성할 때 개별적인 테이블을 가리키는
+경로를 추가하는 방식을 사용합니다. 예를 들어, <em>table1</em>과
+<em>table2</em>라는 테이블이 있다면, 이전 예시의 권한을 조합하여
+콘텐츠 URI<code>com.example.&lt;appname&gt;.provider/table1</code>와
+<code>com.example.&lt;appname&gt;.provider/table2</code>를 도출합니다.
+
+경로는 하나의 세그먼트에 국한되지 않으며, 경로의 각 수준에 대한 테이블이 아니어도 됩니다.
+</p>
+<h3>콘텐츠 URI ID 처리</h3>
+<p>
+ 규칙에 의하면, 제공자는 URI 맨 끝에서 행에 대한 ID 값이 있는 콘텐츠 URI를 허용하여
+테이블 내 하나의 행으로의 액세스를 제공합니다. 또한 규칙에 의해 제공자는
+이 ID 값을 테이블의 <code>_ID</code> 열에 일치시켜야 하며,
+일치한 행에 대하여 요청된 액세스 허가를 수행해야 합니다.
+</p>
+<p>
+ 이 규칙은 제공자에 액세스하는 앱을 위한 공통 설계 패턴을 세우는 데 유용합니다.
+앱이 제공자에 대한 쿼리를 수행하고 그 결과로 나온 {@link android.database.Cursor}를
+{@link android.widget.ListView}에 {@link android.widget.CursorAdapter}를 사용하여 표시합니다.
+ {@link android.widget.CursorAdapter}의 정의에 따르면
+{@link android.database.Cursor} 안의 열 중 하나는 <code>_ID</code>여야 합니다.
+</p>
+<p>
+ 그러면 사용자가 데이터를 살펴보거나 수정하기 위하여
+UI에서 표시된 여러 행 중 하나를 선택합니다. 앱은 {@link android.widget.ListView}를 지원하는 {@link android.database.Cursor}에서 해당하는 열을 가져오고,
+해당 열에 대한 <code>_ID</code> 값을 가져와서
+콘텐츠 URI에 추가하고, 제공자에 액세스 요청을 전송합니다. 그런 다음 제공자는
+사용자가 선택한 바로 그 행에 대해 쿼리 또는 수정 작업을 수행할 수 있습니다.
+</p>
+<h3>콘텐츠 URI 패턴</h3>
+<p>
+ 수신되는 콘텐츠 URI에 대해 어떤 조치를 취할지 선택하는 데 도움이 되도록 하기 위해 제공자 API에
+편의 클래스 {@link android.content.UriMatcher}가
+포함되어 있습니다. 이는 콘텐츠 URI "패턴"을 정수값으로 매핑합니다. 이 정수값은 특정 패턴에 일치하는
+콘텐츠 URI 또는 여러 URI에 대해 원하는 작업을 선택하는 데 <code>switch</code> 문에서 사용할 수 있습니다.
+</p>
+<p>
+ 콘텐츠 URI 패턴은 와일드카드 문자를 사용하는 콘텐츠 URI와 일치합니다.
+</p>
+ <ul>
+ <li>
+ <strong><code>*</code>:</strong> 모든 길이의 모든 유효한 문자로 구성된 문자열과 일치합니다.
+ </li>
+ <li>
+ <strong><code>#</code>:</strong> 모든 길이의 숫자 문자로 구성된 문자열과 일치합니다.
+ </li>
+ </ul>
+<p>
+ 콘텐츠 URI 처리의 설계와 코딩에 대한 예시로서 임의의 제공자를 들어 보겠습니다.
+이 제공자에는 권한 <code>com.example.app.provider</code>가 있고
+이 권한이 테이블을 가리키는 다음 콘텐츠 URI를 인식합니다.
+</p>
+<ul>
+ <li>
+ <code>content://com.example.app.provider/table1</code>: <code>table1</code>이라는 테이블입니다.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset1</code>:
+<code>dataset1</code>이라는 테이블입니다.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset2</code>:
+<code>dataset2</code>라는 테이블입니다.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table3</code>: <code>table3</code>이라는 테이블입니다.
+ </li>
+</ul>
+<p>
+ 제공자는 추가된 행 ID가 있으면 이런 콘텐츠 URI도 인식합니다.
+예를 들어, <code>table3</code>에서 <code>1</code>이 식별한 행에 대한
+<code>content://com.example.app.provider/table3/1</code>이 이에 해당됩니다.
+</p>
+<p>
+ 가능한 콘텐츠 URI 패턴은 다음과 같습니다.
+</p>
+<dl>
+ <dt>
+ <code>content://com.example.app.provider/*</code>
+ </dt>
+ <dd>
+ 제공자에 있는 모든 콘텐츠 URI와 일치합니다.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table2/*</code>:
+ </dt>
+ <dd>
+ 테이블 <code>dataset1</code>과
+<code>dataset2</code>의 콘텐츠 URI와 일치하지만 <code>table1</code>이나
+<code>table3</code>에 대한 콘텐츠 URI와 일치하지 않습니다.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table3/#</code>:
+<code>table3</code>의 단일 행에 대한 콘텐츠 URI와 일치합니다. 예를 들어,
+<code>6</code>이 식별한 행에 대한 <code>content://com.example.app.provider/table3/6</code>이 이에 해당됩니다.
+
+ </dt>
+</dl>
+<p>
+ 다음 코드 조각은 {@link android.content.UriMatcher} 작업에서 메서드의 작용 원리를 나타낸 것입니다.
+ 이 코드는 테이블에 대한 콘텐츠 URI 패턴 <code>content://&lt;authority&gt;/&lt;path&gt;</code>와
+단일 행에 대한 콘텐츠 URI 패턴 <code>content://&lt;authority&gt;/&lt;path&gt;/&lt;id&gt;</code>를 사용하여
+단일 행에 대한 URI와 전체 테이블에 대한 URI를 서로 다르게 처리합니다.
+
+</p>
+<p>
+ {@link android.content.UriMatcher#addURI(String, String, int) addURI()} 메서드는
+권한과 경로를 정수값으로 매핑합니다. 메서드 {@link android.content.UriMatcher#match(Uri)
+match()}는 URI에 대한 정수값을 반환합니다. <code>switch</code> 문이
+전체 테이블을 쿼리할 것인지, 하나의 레코드를 쿼리할 것인지 선택합니다.
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider {
+...
+ // Creates a UriMatcher object.
+ private static final UriMatcher sUriMatcher;
+...
+ /*
+ * The calls to addURI() go here, for all of the content URI patterns that the provider
+ * should recognize. For this snippet, only the calls for table 3 are shown.
+ */
+...
+ /*
+ * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used
+ * in the path
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3", 1);
+
+ /*
+ * Sets the code for a single row to 2. In this case, the "#" wildcard is
+ * used. "content://com.example.app.provider/table3/3" matches, but
+ * "content://com.example.app.provider/table3 doesn't.
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3/#", 2);
+...
+ // Implements ContentProvider.query()
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder) {
+...
+ /*
+ * Choose the table to query and a sort order based on the code returned for the incoming
+ * URI. Here, too, only the statements for table 3 are shown.
+ */
+ switch (sUriMatcher.match(uri)) {
+
+
+ // If the incoming URI was for all of table3
+ case 1:
+
+ if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
+ break;
+
+ // If the incoming URI was for a single row
+ case 2:
+
+ /*
+ * Because this URI was for a single row, the _ID value part is
+ * present. Get the last path segment from the URI; this is the _ID value.
+ * Then, append the value to the WHERE clause for the query
+ */
+ selection = selection + "_ID = " uri.getLastPathSegment();
+ break;
+
+ default:
+ ...
+ // If the URI is not recognized, you should do some error handling here.
+ }
+ // call the code to actually do the query
+ }
+</pre>
+<p>
+ 또 다른 클래스, {@link android.content.ContentUris}가
+콘텐츠 URI의 <code>id</code> 부분을 다루기 위한 편의 메서드를 제공합니다. 클래스 {@link android.net.Uri}와
+{@link android.net.Uri.Builder}에는
+기존 {@link android.net.Uri} 개체를 구문 분석하고 새로운 개체를 구축하기 위한 편의 메서드가 포함되어 있습니다.
+</p>
+
+<!-- Implementing the ContentProvider class -->
+<h2 id="ContentProvider">ContentProvider 클래스 구현</h2>
+<p>
+ {@link android.content.ContentProvider} 인스턴스는
+다른 애플리케이션으로부터의 요청을 처리하여 구조화된 데이터 세트로의 액세스를 관리합니다.
+모든 형태의 액세서가 궁극적으로 {@link android.content.ContentResolver}를 호출하며,
+그러면 이것이 액세스 권한을 얻기 위해 구체적인 {@link android.content.ContentProvider} 메서드를 호출합니다.
+</p>
+<h3 id="RequiredAccess">필수 메서드</h3>
+<p>
+ 추상 클래스 {@link android.content.ContentProvider}는
+개발자가 나름의 구체적인 하위 클래스의 일부분으로 구현해야만 하는 여섯 가지 추상 메서드를 정의합니다. 이와 같은 메서드는 모두
+({@link android.content.ContentProvider#onCreate() onCreate()}는 예외)
+콘텐츠 제공자에 액세스하려 시도 중인 클라이언트 애플리케이션이 호출합니다.
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+query()}
+ </dt>
+ <dd>
+ 제공자에서 데이터를 검색합니다. 인수를 사용하여 쿼리할 테이블과 반환할 열/행, 결과의 정렬 순서를 선택합니다.
+
+ 데이터를 {@link android.database.Cursor} 개체로 반환합니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}
+ </dt>
+ <dd>
+ 제공자에 새로운 행을 삽입합니다. 인수를 사용하여 대상 테이블을 선택하고
+사용할 열 값을 가져옵니다.
+새로 삽입된 행에 대한 콘텐츠 URI를 반환합니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+update()}
+ </dt>
+ <dd>
+ 제공자 내의 기존 행을 업데이트합니다. 인수를 사용하여
+업데이트할 테이블과 행을 선택하고 업데이트한 열 값을 가져옵니다. 업데이트한 행 개수를 반환합니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()}
+ </dt>
+ <dd>
+ 제공자에서 행을 삭제합니다. 인수를 사용하여 삭제할 테이블과 행을 선택합니다.
+ 삭제한 행 개수를 반환합니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ 콘텐츠 URI에 상응하는 MIME 유형을 반환합니다. 이 메서드는
+<a href="#MIMETypes">콘텐츠 제공자 MIME 유형</a> 섹션에 더 자세하게 설명되어 있습니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#onCreate() onCreate()}
+ </dt>
+ <dd>
+ 제공자를 초기화합니다. Android 시스템은 제공자를 생성한 직후
+이 메서드를 호출합니다.
+{@link android.content.ContentResolver} 개체가 제공자에 액세스하려고 시도할 때까지는 제공자가 생성된 것이 아니라는 점을 유의하십시오.
+ </dd>
+</dl>
+<p>
+ 이와 같은 메서드에는 동일하게 이름 붙여진
+{@link android.content.ContentResolver} 메서드와 같은 서명이 있다는 것을 눈여겨 보십시오.
+</p>
+<p>
+ 이러한 메서드의 구현에는 다음과 같은 내용을 감안해야 합니다.
+</p>
+<ul>
+ <li>
+ 이런 메서드는 모두({@link android.content.ContentProvider#onCreate() onCreate()}는 예외)
+ 한꺼번에 여러 스레드가 호출할 수 있으므로, 스레드로부터 안전해야 합니다.
+다중 스레드에 대한 자세한 내용은
+<a href="{@docRoot}guide/components/processes-and-threads.html">
+프로세스 및 스레드</a> 주제를 참조하십시오.
+ </li>
+ <li>
+ {@link android.content.ContentProvider#onCreate()
+onCreate()}에서는 긴 작업을 수행하는 것을 삼가는 것이 좋습니다. 실제로 필요할 때까지 초기화 작업을 미뤄두십시오.
+ 이 내용은 <a href="#OnCreate">onCreate() 메서드 구현</a>
+섹션에서 더욱 자세히 논의합니다.
+ </li>
+ <li>
+ 이와 같은 메서드는 반드시 구현해야 하는 것이지만,
+예상되는 데이터 유형을 반환하는 것 외에 달리 코드가 해야 할 일은 없습니다.
+예를 들어 몇몇 테이블에 다른 애플리케이션이 데이터를 삽입하지 못하도록 방지하려고 합니다. 이렇게 하려면,
+{@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}로의
+호출을 무시하고 0을 반환하면 됩니다.
+ </li>
+</ul>
+<h3 id="Query">query() 메서드 구현</h3>
+<p>
+
+{@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ContentProvider.query()} 메서드는 {@link android.database.Cursor} 개체를 반환해야 하고, 그렇지 못할 경우
+{@link java.lang.Exception}을 발생시킵니다. SQLite 데이터베이스를 데이터 저장소로 사용하는 경우,
+{@link android.database.sqlite.SQLiteDatabase} 클래스의 <code>query()</code> 메서드 중 하나로 반환되는 {@link android.database.Cursor}를
+반환하기만 하면 됩니다.
+ 쿼리가 어느 행에도 일치하지 않으면, {@link android.database.Cursor#getCount()} 메서드가 0을 반환하는
+{@link android.database.Cursor} 인스턴스를 반환해야 합니다.
+ <code>null</code>을 반환하는 것은 쿼리 과정 중에 내부 오류가 발생했을 때뿐입니다.
+</p>
+<p>
+ SQLite 데이터베이스를 데이터 저장소로 사용하지 않는 경우, {@link android.database.Cursor}의
+ 구체적인 하위 클래스 중 하나를 사용하십시오. 예를 들어, {@link android.database.MatrixCursor} 클래스는
+각 행이 {@link java.lang.Object} 배열인 커서를 구현합니다. 이 클래스에서는
+{@link android.database.MatrixCursor#addRow(Object[]) addRow()}를 사용하여 새 행을 추가합니다.
+</p>
+<p>
+ Android 시스템이 프로세스 경계를 가로질러 {@link java.lang.Exception}을
+ 통신으로 전달할 수 있어야 한다는 점을 유의하십시오. Android가 이 작업을 할 수 있는 경우는
+쿼리 오류 처리에 유용할 수 있는 다음과 같은 예외에 해당될 때입니다.
+</p>
+<ul>
+ <li>
+ {@link java.lang.IllegalArgumentException}
+(제공자가 유효하지 않은 콘텐츠 URI를 수신할 경우 이 예외를 발생시킬 수 있습니다.)
+ </li>
+ <li>
+ {@link java.lang.NullPointerException}
+ </li>
+</ul>
+<h3 id="Insert">insert() 메서드 구현</h3>
+<p>
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} 메서드는
+{@link android.content.ContentValues} 인수의 값을 이용하여
+적절한 테이블에 새 행을 추가합니다. 열 이름이 {@link android.content.ContentValues} 인수에 없는 경우,
+제공자 코드 또는 데이터베이스 스키마 내에 그에 대한 기본값을 제공하는 것이 좋을 수도 있습니다.
+
+</p>
+<p>
+ 이 메서드가 새 행에 대한 콘텐츠 URI를 반환하는 것이 정상입니다. 이것을 구성하려면 새 행의
+<code>_ID</code>(또는 다른 기본 키) 값을 테이블의 콘텐츠 URI에 추가하며, 이때
+{@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()}를 사용합니다.
+</p>
+<h3 id="Delete">delete() 메서드 구현</h3>
+<p>
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} 메서드의 경우
+ 데이터 저장소에서 물리적으로 행을 삭제하지 않아도 됩니다.
+제공자와 동기화 어댑터를 함께 사용하고 있는 경우,
+삭제된 행을 완전히 제거하기보다는 "삭제" 플래그로 표시하는 방법을 고려해볼 만합니다.
+동기화 어댑터가 삭제된 행을 확인한 다음, 이를 제공자에서 삭제하기 전에 우선 서버에서 제거합니다.
+</p>
+<h3 id="Update">Update() 메서드 구현</h3>
+<p>
+ {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+update()} 메서드는{@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}가 사용하는 것과 같은 {@link android.content.ContentValues} 인수와
+
+{@link android.content.ContentProvider#delete(Uri, String, String[]) delete()}와 {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ContentProvider.query()}가 사용하는 것과 같은 <code>selection</code> 및 <code>selectionArgs</code> 인수를
+취합니다.
+ 이 때문에 이와 같은 메서드 사이에서 코드를 다시 사용할 수 있게 해주기도 합니다.
+</p>
+<h3 id="OnCreate">onCreate() 메서드 구현</h3>
+<p>
+ Android 시스템은 제공자를 시작할 때 {@link android.content.ContentProvider#onCreate()
+onCreate()}를 호출합니다. 이 메서드에서는 빠르게 실행되는 초기화만 수행해야 하며,
+데이터베이스 생성과 데이터 로딩은 제공자가 실제로 데이터에 대한 요청을 받을 때까지 미뤄두어야 합니다.
+
+{@link android.content.ContentProvider#onCreate() onCreate()}에서 긴 작업을 수행하면
+제공자의 시동 속도가 느려집니다. 이 때문에 제공자에서 다른 애플리케이션으로 전달되는 응답도 따라서 느려집니다.
+
+</p>
+<p>
+ 예를 들어, SQLite 데이터베이스를 사용하는 경우
+{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}에서
+새로운 {@link android.database.sqlite.SQLiteOpenHelper} 개체를 생성하고,
+그런 다음 데이터베이스를 처음 열 때 SQL 테이블을 생성할 수 있습니다. 이를 용이하게 하기 위해
+{@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase
+getWritableDatabase()}를 처음 호출하면 이것이 자동으로
+{@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+SQLiteOpenHelper.onCreate()} 메서드를 호출합니다.
+</p>
+<p>
+ 다음 두 개의 조각은
+{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}와
+{@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+SQLiteOpenHelper.onCreate()} 사이의 상호 작용을 나타낸 것입니다. 첫 번째 조각은
+{@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}의 구현입니다.
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider
+
+ /*
+ * Defines a handle to the database helper object. The MainDatabaseHelper class is defined
+ * in a following snippet.
+ */
+ private MainDatabaseHelper mOpenHelper;
+
+ // Defines the database name
+ private static final String DBNAME = "mydb";
+
+ // Holds the database object
+ private SQLiteDatabase db;
+
+ public boolean onCreate() {
+
+ /*
+ * Creates a new helper object. This method always returns quickly.
+ * Notice that the database itself isn't created or opened
+ * until SQLiteOpenHelper.getWritableDatabase is called
+ */
+ mOpenHelper = new MainDatabaseHelper(
+ getContext(), // the application context
+ DBNAME, // the name of the database)
+ null, // uses the default SQLite cursor
+ 1 // the version number
+ );
+
+ return true;
+ }
+
+ ...
+
+ // Implements the provider's insert method
+ public Cursor insert(Uri uri, ContentValues values) {
+ // Insert code here to determine which table to open, handle error-checking, and so forth
+
+ ...
+
+ /*
+ * Gets a writeable database. This will trigger its creation if it doesn't already exist.
+ *
+ */
+ db = mOpenHelper.getWritableDatabase();
+ }
+}
+</pre>
+<p>
+ 그 다음 조각은
+도우미 클래스를 포함한 {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+SQLiteOpenHelper.onCreate()}의 구현입니다.
+</p>
+<pre class="prettyprint">
+...
+// A string that defines the SQL statement for creating a table
+private static final String SQL_CREATE_MAIN = "CREATE TABLE " +
+ "main " + // Table's name
+ "(" + // The columns in the table
+ " _ID INTEGER PRIMARY KEY, " +
+ " WORD TEXT"
+ " FREQUENCY INTEGER " +
+ " LOCALE TEXT )";
+...
+/**
+ * Helper class that actually creates and manages the provider's underlying data repository.
+ */
+protected static final class MainDatabaseHelper extends SQLiteOpenHelper {
+
+ /*
+ * Instantiates an open helper for the provider's SQLite data repository
+ * Do not do database creation and upgrade here.
+ */
+ MainDatabaseHelper(Context context) {
+ super(context, DBNAME, null, 1);
+ }
+
+ /*
+ * Creates the data repository. This is called when the provider attempts to open the
+ * repository and SQLite reports that it doesn't exist.
+ */
+ public void onCreate(SQLiteDatabase db) {
+
+ // Creates the main table
+ db.execSQL(SQL_CREATE_MAIN);
+ }
+}
+</pre>
+
+
+<!-- Implementing ContentProvider MIME Types -->
+<h2 id="MIMETypes">ContentProvider MIME 유형 구현</h2>
+<p>
+ {@link android.content.ContentProvider} 클래스에는 MIME 유형을 반환하는 두 가지 메서드가 있습니다.
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ 모든 제공자에 대해 구현해야 하는 필수 메서드 중 하나입니다.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}
+ </dt>
+ <dd>
+ 제공자가 파일을 제공하는 경우 구현해야 하는 메서드입니다.
+ </dd>
+</dl>
+<h3 id="TableMIMETypes">테이블의 MIME 유형</h3>
+<p>
+ {@link android.content.ContentProvider#getType(Uri) getType()} 메서드는
+콘텐츠 URI 인수가 반환하는 데이터 유형을 설명하는 MIME 형식의 {@link java.lang.String}을 반환합니다.
+ {@link android.net.Uri} 인수는 특정 URI라기보다 패턴일 수 있습니다.
+이 경우, 이 패턴과 일치하는 콘텐츠 URI와 연관된 유형의 데이터를 반환해야 합니다.
+
+</p>
+<p>
+ 텍스트, HTML 또는 JPEG와 같은 보편적인 유형의 데이터라면
+{@link android.content.ContentProvider#getType(Uri) getType()}이
+해당 데이터에 대한 표준 MIME 유형을 반환하는 것이 정상입니다. 이러한 표준 유형의 전체 목록은
+<a href="http://www.iana.org/assignments/media-types/index.htm">IANA MIME 미디어 유형</a>
+웹사이트에서 확인할 수 있습니다.
+</p>
+<p>
+ 테이블 데이터의 행 하나 또는 여러 행을 가리키는 콘텐츠 URI의 경우,
+{@link android.content.ContentProvider#getType(Uri) getType()}이 Android의 공급업체별 MIME 형식에서
+MIME 형식을 반환해야 합니다.
+</p>
+<ul>
+ <li>
+ 유형 부분: <code>vnd</code>
+ </li>
+ <li>
+ 하위 유형 부분:
+ <ul>
+ <li>
+ URI 패턴이 하나의 행에 대한 것일 경우: <code>android.cursor.<strong>item</strong>/</code>
+ </li>
+ <li>
+ URI 패턴이 하나 이상의 행에 대한 것일 경우: <code>android.cursor.<strong>dir</strong>/</code>
+ </li>
+ </ul>
+ </li>
+ <li>
+ 제공자별 부분: <code>vnd.&lt;name&gt;</code>.<code>&lt;type&gt;</code>
+ <p>
+ 개발자가 <code>&lt;name&gt;</code>과 <code>&lt;type&gt;</code>을 제공합니다.
+ <code>&lt;name&gt;</code> 값은 전체적으로 고유해야 하고,
+<code>&lt;type&gt;</code> 값은 상응하는 URI 패턴에 고유해야
+합니다. <code>&lt;name&gt;</code>으로 좋은 예는 회사 이름이나
+애플리케이션의 Android 패키지 이름을 들 수 있습니다.
+<code>&lt;type&gt;</code>으로 좋은 예는 URI와 연관된 테이블을 식별하는
+문자열을 들 수 있습니다.
+ </p>
+
+ </li>
+</ul>
+<p>
+ 예를 들어 어떤 제공자의 권한이
+<code>com.example.app.provider</code>이고, 이것이
+<code>table1</code>이라는 테이블을 노출하는 경우, <code>table1</code>의 여러 행에 대한 MIME 유형은 다음과 같습니다.
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1
+</pre>
+<p>
+ <code>table1</code>의 행 하나의 경우, MIME 유형은 다음과 같습니다.
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1
+</pre>
+<h3 id="FileMIMETypes">파일의 MIME 유형</h3>
+<p>
+ 제공자가 파일을 제공하는 경우,
+{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}를 구현합니다.
+ 이 메서드는 제공자가 주어진 콘텐츠 URI에 대해 반환할 수 있는 파일에 대한 MIME 유형의 {@link java.lang.String} 배열을 반환합니다.
+제공하는 MIME 유형을 MIME 유형 필터 인수 기준으로 필터링해야
+클라이언트가 처리하고자 하는 MIME 유형만 반환할 수 있습니다.
+</p>
+<p>
+ 예를 들어, 사진 이미지를 <code>.jpg</code>,
+<code>.png</code> 및 <code>.gif</code> 형식의 파일로 제공하는 제공자가 있다고 하겠습니다.
+ 애플리케이션이 필터 문자열 <code>image/*</code>("이미지"인 어떤 것)로 {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ContentResolver.getStreamTypes()}를 호출하면
+
+{@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ContentProvider.getStreamTypes()} 메서드가 다음과 같은 배열을 반환하는 것이 정상입니다.
+</p>
+<pre>
+{ &quot;image/jpeg&quot;, &quot;image/png&quot;, &quot;image/gif&quot;}
+</pre>
+<p>
+ 앱이 <code>.jpg</code> 파일에만 관심이 있는 경우에는
+필터 문자열 <code>*\/jpeg</code>으로 {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ ContentResolver.getStreamTypes()}를 호출할 수 있습니다. 그러면
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ ContentProvider.getStreamTypes()}가 다음과 같이 반환하는 것이 정상입니다.
+<pre>
+{&quot;image/jpeg&quot;}
+</pre>
+<p>
+ 제공자가 필터 문자열에서 요청한 MIME 유형 중 제공하는 것이 없는 경우,
+{@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}가
+ <code>null</code>을 반환하는 것이 정상입니다.
+</p>
+
+
+<!-- Implementing a Contract Class -->
+<h2 id="ContractClass">계약 클래스 구현</h2>
+<p>
+ 계약 클래스는 <code>public final</code> 클래스로, 이 안에 URI, 열 이름, MIME 유형의
+상수 정의 및 제공자에 관련된 다른 메타 데이터가 들어 있습니다.
+이 클래스는 URI, 열 이름 등의 실제 값에 변경된 내용이 있더라도
+ 제공자에 올바르게 액세스할 수 있도록 보장하여 제공자와
+다른 애플리케이션 사이의 계약을 확립합니다.
+</p>
+<p>
+ 계약 클래스가 개발자에게 유용한 이유는 또 있습니다. 이 클래스는 보통 자신의 상수 이름으로
+니모닉 이름을 가지기 때문에 개발자가 열 이름 또는 URI에 잘못된 값을 사용할 가능성이 덜합니다.
+이것도 클래스의 일종이기 때문에 Javadoc 문서를 포함할 수 있습니다.
+Eclipse와 같은 통합 개발 환경은 계약 클래스의 상수 이름을 자동 완성하고
+해당 상수에 대한 Javadoc을 표시할 수 있습니다.
+</p>
+<p>
+ 개발자가 애플리케이션에서 계약 클래스의 클래스 파일에 액세스할 수는 없지만
+여러분이 제공하는 <code>.jar</code> 파일에서 이를 애플리케이션 안으로 정적으로 컴파일링할 수 있습니다.
+</p>
+<p>
+ {@link android.provider.ContactsContract} 클래스와
+이에 중첩된 클래스가 계약 클래스의 예시입니다.
+</p>
+<h2 id="Permissions">콘텐츠 제공자 권한 구현</h2>
+<p>
+ Android 시스템의 모든 측면에 대한 권한과 액세스는
+<a href="{@docRoot}guide/topics/security/security.html">보안 및 권한</a> 주제에 설명되어 있습니다.
+ <a href="{@docRoot}guide/topics/data/data-storage.html">데이터 저장소</a> 주제에서도
+다양한 유형의 저장소에 적용되는 보안 및 권한을 설명하고 있습니다.
+ 간략히 말해 요점은 다음과 같습니다.
+</p>
+<ul>
+ <li>
+ 기본적으로, 기기의 내부 저장소에 저장된 데이터 파일은
+본인의 애플리케이션과 제공자 전용입니다.
+ </li>
+ <li>
+ 본인이 생성한 {@link android.database.sqlite.SQLiteDatabase} 데이터베이스는
+본인의 애플리케이션과 제공자만의 비공개 데이터입니다.
+ </li>
+ <li>
+ 기본적으로 외부 저장소에 저장하는 데이터 파일은 <em>공개</em>이고
+<em>누구나 읽을 수 있습니다</em>. 외부 저장소에 있는 파일로의 액세스를 제공하는 데 콘텐츠 제공자를 쓸 수는
+없습니다. 다른 애플리케이션이 다른 API 호출을 사용하여 해당 파일을 읽고 쓸 수 있기 때문입니다.
+ </li>
+ <li>
+ 기기의 내부 저장소에 있는 파일 또는 SQLite 데이터베이스를 열거나 생성하기 위한 메서드 호출은
+다른 모든 애플리케이션에 읽기 및 쓰기 액세스 권한을 허가할 가능성이 있습니다.
+내부 파일이나 데이터베이스를 제공자의 리포지토리로 사용하고
+"누구나 읽을 수 있는" 또는 "누구나 쓸 수 있는" 액세스를 부여하면
+매니페스트에서 제공자에 대해 설정한 권한이 데이터를 보호하지 못합니다.
+내부 저장소 안에 있는 파일과 데이터베이스에 대한기본 액세스는 "비공개"이며, 제공자의 리포지토리가 이것을 변경하면 안 됩니다.
+ </li>
+</ul>
+<p>
+ 데이터로의 액세스를 제어하기 위해 콘텐츠 제공자 권한을 쓰고자 하는 경우,
+데이터를 내부 파일, SQLite 데이터베이스 또는 "클라우드"(예: 원격 서버) 안의
+내부 파일로 저장해야 하고, 파일과 데이터베이스를 애플리케이션만의 비공개로 유지해야 합니다.
+</p>
+<h3>권한 구현</h3>
+<p>
+ 기본 데이터가 비공개라고 하더라도 모든 애플리케이션이 제공자를 읽고 제공자에 쓸 수 있습니다.
+기본적으로 제공자에는 권한이 설정되어 있지 않기 때문입니다. 이를 변경하려면,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소의 속성이나 하위 요소를 사용하여
+매니페스트 파일에 있는 제공자의 권한을 설정합니다. 권한은 제공자 전체에 적용되도록 설정할 수도 있고,
+특정 테이블에, 또는 심지어 특정 레코드에 적용되게 할 수도 있고 세 가지 모두를 택할 수도 있습니다.
+</p>
+<p>
+ 제공자에 대한 권한은 매니페스트 파일에 있는 하나 이상의
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">
+ &lt;permission&gt;</a></code> 요소로 정의합니다.
+제공자에 고유한 권한을 설정하려면
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm">
+ android:name</a></code> 속성에 Java 스타일 범위를 사용합니다. 예를 들어 읽기 권한의 이름을
+<code>com.example.app.provider.permission.READ_PROVIDER</code>로 지정합니다.
+
+</p>
+<p>
+ 다음 목록은 제공자 권한의 범위를 설명한 것입니다.
+제공자 전체에 적용되는 권한부터 시작하여 점차 세분화된 권한이 됩니다.
+ 보다 세부화된 권한이 범위가 큰 것보다 우선합니다.
+</p>
+<dl>
+ <dt>
+ 단일 읽기-쓰기 제공자 수준 권한
+ </dt>
+ <dd>
+ 제공자 전체로의 읽기와 쓰기 액세스 양쪽 모두를 제어하는 하나의 권한으로,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소의
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code> 속성으로 지정됩니다.
+ </dd>
+ <dt>
+ 별도의 읽기 및 쓰기 제공자 수준 권한
+ </dt>
+ <dd>
+ 제공자 전체에 대한 읽기 권한과 쓰기 권한입니다. 이들 권한은
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소의 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code>와
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code> 속성으로
+지정합니다. 이들이
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>에서 요구하는 권한보다 우선합니다.
+ </dd>
+ <dt>
+ 경로 수준 권한
+ </dt>
+ <dd>
+ 제공자의 콘텐츠 URI에 대한 읽기, 쓰기 또는 읽기/쓰기 권한입니다. 제어하고자 하는 각 URI를 직접 지정하되,
+이때
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소의
+<code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">
+ &lt;path-permission&gt;</a></code> 하위 요소를 사용합니다. 지정하는 콘텐츠 URI마다
+읽기/쓰기 권한, 읽기 권한 또는 쓰기 권한을 하나씩 지정하거나 셋 모두를 지정할 수 있습니다.
+읽기 및 쓰기 권한이 읽기/쓰기 권한보다 우선합니다.
+또한, 경로 수준 권한이 제공자 수준 권한보다 우선합니다.
+ </dd>
+ <dt>
+ 임시 권한
+ </dt>
+ <dd>
+ 애플리케이션에 임시 액세스를 허용하는 권한 수준입니다.
+해당 애플리케이션에 일반적으로 요구되는 권한이 없더라도 무관합니다.
+임시 액세스 기능은 매니페스트에서 요청해야 하는
+권한과 애플리케이션 개수를 줄여줍니다. 임시 권한을 사용하는 경우,
+제공자에 대하여 "영구" 권한을 필요로하는 애플리케이션은
+모든 데이터에 지속적으로 액세스하는 것들뿐입니다.
+ <p>
+ 이메일 제공자와 앱을 구현할 때 필요한 권한을 예로 들어 보겠습니다.
+외부 이미지 뷰어 애플리케이션으로 하여금 제공자에서 보낸 사진 첨부 파일을
+표시하도록 허용하고자 한다고 가정합니다. 권한을 요구하지 않고 이미지 뷰어에 필수 액세스를 부여하려면,
+사진에 대한 콘텐츠 URI에 해단되는 임시 권한을 설정하십시오.
+사용자가 사진을 표시하기를 원할 때 앱이 사진의 콘텐츠 URI와 권한 플래그를 포함하는 인텐트를
+이미지 뷰어에 보내도록 이메일 앱을 설계합니다. 그러면 해당 이미지 뷰어가
+이메일 제공자에 사진 검색을 쿼리할 수 있으며, 이 뷰어에 제공자에 대한 정상적인 읽기 권한이 없더라도 무방합니다.
+
+ </p>
+ <p>
+ 임시 권한을 사용하려면,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소의 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> 속성을 설정하거나
+하나 이상의
+<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> 하위 요소를
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소에 추가하면 됩니다. 임시 권한을 사용하는 경우,
+제공자에서 콘텐츠 URI에 대한 지원을 제거할 때마다 {@link android.content.Context#revokeUriPermission(Uri, int)
+ Context.revokeUriPermission()}을 호출해야 합니다.
+그러면 콘텐츠 URI가 임시 권한과 연관됩니다.
+ </p>
+ <p>
+ 속성의 값에 따라 제공자에 액세스 가능한 정도가 결정됩니다.
+ 속성이 <code>true</code>로 설정되어 있는 경우라면
+시스템이 제공자 전체에 임시 권한을 허용하며, 제공자 수준 또는
+경로 수준 권한에서 요구하는 다른 모든 권한을 재정의합니다.
+ </p>
+ <p>
+ 이 플래그가 <code>false</code>로 설정되면, 반드시
+<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> 하위 요소를
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소에 추가해야 합니다. 각 하위 요소는 임시 권한을 허용한
+콘텐츠 URI(하나 또는 여러 개)를 나타냅니다.
+ </p>
+ <p>
+ 애플리케이션에 임시 액세스를 위임하려면, 인텐트에
+{@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} 또는
+{@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} 플래그, 또는 둘 모두가 들어 있어야 합니다. 이들은
+{@link android.content.Intent#setFlags(int) setFlags()} 메서드로 설정됩니다.
+ </p>
+ <p>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> 속성이 존재하지 않으면
+<code>false</code>인 것으로 가정합니다.
+ </p>
+ </dd>
+</dl>
+
+
+
+<!-- The Provider Element -->
+<h2 id="ProviderElement">&lt;provider&gt; 요소</h2>
+<p>
+ {@link android.app.Activity}와 {@link android.app.Service} 구성 요소와 마찬가지로,
+{@link android.content.ContentProvider}의 하위 클래스는
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> 요소를 사용하여 매니페스트 파일에서
+애플리케이션에 대해 정의되어야 합니다. Android 시스템이
+해당 요소에서 다음과 같은 정보를 가져옵니다.
+<dl>
+ <dt>
+ 권한
+(<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code
+android:authorities}</a>)
+ </dt>
+ <dd>
+ 시스템 내에서 제공자 전체를 식별하는 상징적 이름입니다. 이 속성은
+
+<a href="#ContentURI">콘텐츠 URI 설계</a> 섹션에서 자세히 설명되어 있습니다.
+ </dd>
+ <dt>
+ 제공자 클래스 이름
+(<code>
+<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a>
+ </code>)
+ </dt>
+ <dd>
+ {@link android.content.ContentProvider}를 구현하는 클래스입니다. 이 클래스는
+
+<a href="#ContentProvider">ContentProvider 클래스 구현</a> 섹션에 자세히 설명되어 있습니다.
+ </dd>
+ <dt>
+ 권한
+ </dt>
+ <dd>
+ 제공자의 데이터에 액세스하기 위해 다른 애플리케이션이
+반드시 가지고 있어야 하는 권한을 나타내는 속성입니다.
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermssions</a></code>: 임시 권한 플래그입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>: 단일 제공자 전범위 읽기/쓰기 권한입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code>: 제공자 전범위 읽기 권한입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code>: 제공자 전범위 쓰기 권한입니다.
+ </li>
+ </ul>
+ <p>
+ 각종 권한과 그에 상응하는 속성은
+
+<a href="#Permissions">콘텐츠 제공자 권한 구현</a> 섹션에 자세히 설명되어 있습니다.
+ </p>
+ </dd>
+ <dt>
+ 시작 및 제어 속성
+ </dt>
+ <dd>
+ 이와 같은 속성은 Android 시스템이 제공자를 시작하는 방법과 시점,
+제공자의 프로세스 특징과 기타 런타임 설정 등을 결정합니다.
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled">
+ android:enabled</a></code>: 시스템이 제공자를 시작할 수 있게 해주는 플래그입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
+ android:exported</a></code>: 다른 애플리케이션이 이 제공자를 사용할 수 있게 해주는 플래그입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init">
+ android:initOrder</a></code>: 같은 프로세스 내의 다른 제공자와 비교하여
+이 제공자가 시작되어야 하는 순서입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi">
+ android:multiProcess</a></code>: 클라이언트를 호출하는 것과
+같은 프로세스에서 시스템이 제공자를 시작할 수 있게 해주는 플래그입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc">
+ android:process</a></code>: 제공자가 실행해야 하는 프로세스의
+이름입니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync">
+ android:syncable</a></code>: 제공자의 데이터가
+서버에 있는 데이터와 동기화될 예정임을 나타내는 플래그입니다.
+ </li>
+ </ul>
+ <p>
+ 이 속성은
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>
+요소에 대한 개발자 가이드 주제에 상세하게 기록되어 있습니다.
+ </p>
+ </dd>
+ <dt>
+ 정보 속성
+ </dt>
+ <dd>
+ 제공자에 대한 선택 항목 아이콘 및 레이블입니다.
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon">
+ android:icon</a></code>: 제공자의 아이콘이 들어 있는 드로어블 리소스입니다.
+ 이 아이콘은
+<em>설정</em> &gt; <em>앱</em> &gt; <em>모두</em>에 있는 앱 목록에서 제공자의 레이블 옆에 표시됩니다.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label">
+ android:label</a></code>: 제공자 또는 그 데이터, 또는 둘 모두를 설명하는 정보 레이블입니다.
+ 이 레이블은
+<em>설정</em> &gt; <em>앱</em> &gt; <em>모두</em>에 있는 앱 목록에 표시됩니다.
+ </li>
+ </ul>
+ <p>
+ 이 속성은
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>요소에 대한 개발자 가이드 주제에 상세하게 기록되어 있습니다.
+ </p>
+ </dd>
+</dl>
+
+<!-- Intent Access -->
+<h2 id="Intents">인텐트 및 데이터 액세스</h2>
+<p>
+ 애플리케이션이 콘텐츠 제공자에 간접적으로 액세스하려면 {@link android.content.Intent}를 사용하면 됩니다.
+ 이 애플리케이션은 {@link android.content.ContentResolver} 또는
+{@link android.content.ContentProvider}의 메서드 중 어느 하나도 호출하지 않습니다.
+대신, 액티비티를 시작하는 인텐트를 전송합니다. 이 인텐트는 제공자가 소유한 애플리케이션의 일부인 경우가 많습니다.
+대상 액티비티가 데이터를 자체 UI에서 검색하고 표시하는 역할을 맡습니다.
+인텐트의 동작에 따라 대상 액티비티가 사용자에게 프롬프트를 표시하여 제공자의 데이터를 수정하도록 할 수도 있습니다.
+ 인텐트에는 대상 액티비티가 UI에 표시하는 "추가" 데이터가 들어 있을 수도 있습니다.
+그러면 사용자에게 이 데이터를 변경할 수 있는 옵션이 주어지고, 그런 다음 이를 사용하여
+제공자 내의 데이터를 수정할 수 있습니다.
+</p>
+<p>
+
+</p>
+<p>
+ 데이터 무결성을 보장하는 데 유용한 것을 원하면 인텐트 액세스를 사용하는 것이 좋습니다.
+엄격하게 정의된 비즈니스 논리에 따라 데이터가 삽입, 업데이트되고 삭제되는 것이 제공자를 크게 좌우할 수도 있습니다.
+이런 경우에 해당되면, 다른 애플리케이션에 데이터를 직접 수정하도록 허용하면 데이터가 잘못되는
+결과를 초래할 수 있습니다. 개발자들에게 인텐트 액세스 사용을 허용하려면, 그 내용을 철저히 기록해두어야 합니다.
+ 개발자들에게 자기 애플리케이션의 UI를 사용한 인텐트 액세스가
+코드로 데이터를 수정하려 시도하는 것보다 나은 이유를 설명해주십시오.
+</p>
+<p>
+ 제공자의 데이터를 수정하고자 하는 수신되는 인텐트 처리도 다른 인텐트 처리와 다를 바가 없습니다.
+ 인텐트 사용에 대한 자세한 내용은
+<a href="{@docRoot}guide/components/intents-filters.html">인텐트 및 인텐트 필터</a> 주제를 읽으면 확인할 수 있습니다.
+</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/content-providers.jd b/docs/html-intl/intl/ko/guide/topics/providers/content-providers.jd
new file mode 100644
index 000000000000..ce98840e16db
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/content-providers.jd
@@ -0,0 +1,108 @@
+page.title=콘텐츠 제공자
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<!-- In this document -->
+<h2>주제</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ 콘텐츠 제공자 기본 정보</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ 콘텐츠 제공자 생성</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">캘린더 제공자</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/contacts-provider.html">연락처 제공자</a>
+ </li>
+</ol>
+
+ <!-- Related Samples -->
+<h2>관련 샘플</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ 연락처 관리자</a> 애플리케이션
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ "커서(피플 애플리케이션)"
+ </a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ "커서(전화)"</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ 샘플 동기화 어댑터</a>
+ </li>
+ </ol>
+</div>
+</div>
+<p>
+ 콘텐츠 제공자는 구조화된 데이터 세트로의 액세스를 관리합니다.
+데이터를 캡슐화하여 데이터 보안을 정의하는 데 필요한 메커니즘을 제공하기도 합니다.
+콘텐츠 제공자는 한 프로세스의 데이터에 다른 프로세스에서 실행 중인 코드를 연결하는 표준 인터페이스입니다.
+</p>
+<p>
+ 콘텐츠 제공자 내의 데이터에 액세스하고자 하는 경우,
+애플리케이션의 {@link android.content.Context}에 있는
+{@link android.content.ContentResolver} 개체를 사용하여 클라이언트로서 제공자와 통신을 주고받으면 됩니다.
+ {@link android.content.ContentResolver} 개체가 제공자 개체와 통신하며, 이 개체는
+{@link android.content.ContentProvider}를 구현하는 클래스의 인스턴스입니다.
+제공자 개체가 클라이언트로부터 데이터 요청을 받아 요청된 작업을 수행하며 결과를 반환합니다.
+
+</p>
+<p>
+ 데이터를 다른 애플리케이션과 공유할 생각이 없으면 나름의 제공자를 개발하지 않아도 됩니다.
+ 그러나, 자체 애플리케이션에서 사용자 지정 검색 제안을 제공하려면 나름의 제공자가 꼭 필요합니다.
+ 또한, 복잡한 데이터나 파일을 자신의 애플리케이션에서 다른 애플리케이션으로 복사하여 붙여넣고자 하는 경우에도
+나름의 제공자가 필요합니다.
+</p>
+<p>
+ Android 자체에 오디오, 동영상, 이미지 및 개인 연락처 정보 등의 데이터를 관리하는 콘텐츠 제공자가
+포함되어 있습니다. 그중 몇 가지를 목록으로 나열한 것을
+
+<code><a href="{@docRoot}reference/android/provider/package-summary.html">android.provider</a>
+ </code> 패키지에 대한 참조 문서에서 확인할 수 있습니다. 이와 같은 제공자는 몇 가지 제약이 있지만,
+어느 Android 애플리케이션에나 액세스할 수 있습니다.
+</p><p>
+ 다음 주제에서는 콘텐츠 제공자에 대해 좀 더 자세히 설명합니다.
+</p>
+<dl>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ 콘텐츠 제공자 기본 정보</a></strong>
+ </dt>
+ <dd>
+ 데이터가 여러 개의 표로 정리되어 있을 때 콘텐츠 제공자 내의 데이터에 액세스하는 방법입니다.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ 콘텐츠 제공자 생성</a></strong>
+ </dt>
+ <dd>
+ 나름의 콘텐츠 제공자를 직접 만드는 방법입니다.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ 캘린더 제공자</a></strong>
+ </dt>
+ <dd>
+ Android 플랫폼의 일부인 캘린더 제공자에 액세스하는 방법입니다.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/contacts-provider.html">
+ 연락처 제공자</a></strong>
+ </dt>
+ <dd>
+ Android 플랫폼의 일부인 연락처 제공자에 액세스하는 방법입니다.
+ </dd>
+</dl>
diff --git a/docs/html-intl/intl/ko/guide/topics/providers/document-provider.jd b/docs/html-intl/intl/ko/guide/topics/providers/document-provider.jd
new file mode 100644
index 000000000000..e356e22d17c9
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/providers/document-provider.jd
@@ -0,0 +1,916 @@
+page.title=저장소 액세스 프레임워크
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">더 많은 결과 보기</span>
+ <span class="less" style="display:none">결과 숨기기</span></a></h2>
+<ol id="toc44" class="hide-nested">
+ <li>
+ <a href="#overview">개요</a>
+ </li>
+ <li>
+ <a href="#flow">제어 흐름</a>
+ </li>
+ <li>
+ <a href="#client">클라이언트 앱 작성</a>
+ <ol>
+ <li><a href="#search">문서 검색</a></li>
+ <li><a href="#process">결과 처리</a></li>
+ <li><a href="#metadata">문서 메타데이터 살펴보기</a></li>
+ <li><a href="#open">문서 열기</a></li>
+ <li><a href="#create">새 문서 생성하기</a></li>
+ <li><a href="#delete">문서 삭제하기</a></li>
+ <li><a href="#edit">문서 편집하기</a></li>
+ <li><a href="#permissions">권한 유지</a></li>
+ </ol>
+ </li>
+ <li><a href="#custom">사용자 지정 문서 제공자 작성하기</a>
+ <ol>
+ <li><a href="#manifest">매니페스트</a></li>
+ <li><a href="#contract">계약</a></li>
+ <li><a href="#subclass">하위 클래스 DocumentsProvider</a></li>
+ <li><a href="#security">보안</a></li>
+ </ol>
+ </li>
+
+</ol>
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.provider.DocumentsProvider}</li>
+ <li>{@link android.provider.DocumentsContract}</li>
+</ol>
+
+<h2>비디오</h2>
+
+<ol>
+ <li><a href="http://www.youtube.com/watch?v=zxHVeXbK1P4">
+DevBytes: Android 4.4 저장소 액세스 프레임워크: 제공자</a></li>
+ <li><a href="http://www.youtube.com/watch?v=UFj9AEz0DHQ">
+DevBytes: Android 4.4 저장소 액세스 프레임워크: 클라이언트</a></li>
+</ol>
+
+
+<h2>코드 샘플</h2>
+
+<ol>
+ <li><a href="{@docRoot}samples/StorageProvider/index.html">
+저장소 제공자</a></li>
+ <li><a href="{@docRoot}samples/StorageClient/index.html">
+StorageClient</a></li>
+</ol>
+
+<h2>참고 항목</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ 콘텐츠 제공자 기본 정보
+ </a>
+ </li>
+</ol>
+
+</div>
+</div>
+
+
+<p>Android 4.4(API 레벨 19)에서는 저장소 액세스 프레임워크(SAF)를 처음 도입하게 되었습니다. SAF는
+사용자가 선호하는 문서 저장소 제공자 전체를 걸쳐 문서, 이미지 및 각종 다른 파일을
+탐색하고 여는 작업을 간편하게 만들어줍니다. 표준형의, 사용하기 쉬운 UI로
+사용자가 각종 앱과 제공자에 걸쳐 일관된 방식으로 파일을 탐색하고 최근 내용에 액세스할 수 있게 해줍니다.</p>
+
+<p>클라우드 또는 로컬 저장소 서비스가 이 에코시스템에 참가하려면 자신의 서비스를 캡슐화하는
+{@link android.provider.DocumentsProvider}를 구현하면 됩니다.
+제공자의 문서에 액세스해야 하는 클라이언트 앱의 경우 단 몇 줄의 코드만으로
+SAF와 통합할 수 있습니다.</p>
+
+<p>SAF에는 다음과 같은 항목이 포함됩니다.</p>
+
+<ul>
+<li><strong>문서 제공자</strong>&mdash;일종의 콘텐츠 제공자로
+저장소 서비스(예: Google Drive 등)로 하여금 자신이 관리하는 파일을 드러내도록 허용합니다. 문서 제공자는
+{@link android.provider.DocumentsProvider} 클래스의 하위 클래스로 구현됩니다.
+문서 제공자 스키마는 기존의 파일 계층을 근거로 하지만,
+문서 제공자가 데이터를 저장하는 물리적인 방법은 개발자가 선택하기 나름입니다.
+Android 플랫폼에는 내장된 문서 제공자가 여러 개 있습니다.
+예를 들어 다운로드, 이미지 및 비디오 등입니다.</li>
+
+<li><strong>클라이언트 앱</strong>&mdash;일종의 사용자 지정 앱으로
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 및/또는
+{@link android.content.Intent#ACTION_CREATE_DOCUMENT} 인텐트를 호출하고,
+문서 제공자가 반환하는 파일을 수신합니다.</li>
+
+<li><strong>선택기</strong>&mdash;일종의 시스템 UI로 사용자가 클라이언트 앱의
+검색 기준을 만족하는 모든 문서 제공자에서 문서에 액세스할 수 있도록 해줍니다.</li>
+</ul>
+
+<p>SAF가 제공하는 기능을 몇 가지 예로 들면 다음과 같습니다.</p>
+<ul>
+<li>사용자들로 하여금 하나의 앱만이 아니라 모든 문서 제공자에서 콘텐츠를 탐색할 수 있게 해줍니다.</li>
+<li>여러분의 앱이 문서 제공자가 소유한 문서에 대한 장기적, 영구적 액세스 권한을 가질 수 있도록
+해줍니다. 이 액세스 권한을 통해 사용자가 제공자에 있는 파일을 추가, 편집,
+저장 및 삭제할 수 있습니다.</li>
+<li>여러 개의 사용자 계정을 지원하며 USB 저장소 제공자와 같은 임시 루트도 지원합니다.
+이는 드라이브가 연결되어 있을 때만 나타납니다. </li>
+</ul>
+
+<h2 id ="overview">개요</h2>
+
+<p>SAF는 {@link android.provider.DocumentsProvider} 클래스의
+하위 클래스인 콘텐츠 제공자를 중심으로 둘러싸고 있습니다. 데이터는 <em>문서 제공자</em> 내에서 일반적인 파일 계층으로
+구조화됩니다.</p>
+<p><img src="{@docRoot}images/providers/storage_datamodel.png" alt="data model" /></p>
+<p class="img-caption"><strong>그림 1.</strong> 문서 제공자 데이터 모델입니다. 루트 하나가 하나의 문서를 가리키며,
+이는 다시 트리 전체의 팬아웃을 시작합니다.</p>
+
+<p>다음 내용을 참고하십시오.</p>
+<ul>
+
+<li>각 문서 제공자는 하나 이상의 "루트"를 보고합니다.
+이는 문서 트리 속을 탐색할 시작 지점입니다.
+각 루트에는 고유한 {@link android.provider.DocumentsContract.Root#COLUMN_ROOT_ID}가 있으며,
+이는 해당 루트 아래의 콘텐츠를 나타내는 문서(디렉터리)를
+가리킵니다.
+루트는 설계상 동적으로 만들어져 있어 여러 개의 계정, 임시 USB 저장소 기기
+또는 사용자 로그인/로그아웃 등과 같은 경우를 지원하도록 되어 있습니다.</li>
+
+<li>각 루트 아래에 문서가 하나씩 있습니다. 해당 문서는 1부터 <em>N</em>까지의 문서를 가리키는데,
+이는 각각 1부터 <em>N</em>의 문서를 가리킬 수 있습니다. </li>
+
+<li>각 저장소의 백엔드가
+개별적인 파일과 디렉터리를 고유한
+{@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID}로
+참조하여 드러냅니다.문서 ID는 고유해야 하며 한 번 발행되고 나면 변경되지 않습니다.
+이들은 기기 재부팅을 통괄하여 영구적인 URI 허가에 사용되기 때문입니다.</li>
+
+
+<li>문서는 열 수 있는 파일이거나(특정 MIME 유형으로),
+추가 문서가 들어있는 디렉터리일 수 있습니다(
+{@link android.provider.DocumentsContract.Document#MIME_TYPE_DIR} MIME 유형으로).</li>
+
+<li>각 문서는 서로 다른 기능을 가지고 있을 수 있습니다. 이는
+{@link android.provider.DocumentsContract.Document#COLUMN_FLAGS COLUMN_FLAGS}에서 설명한 것과 같습니다.
+ 예를 들어 {@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_WRITE},
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE} 및
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_THUMBNAIL} 등입니다.
+같은 {@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID}가
+여러 디렉터리에 포함되어 있을 수도 있습니다.</li>
+</ul>
+
+<h2 id="flow">제어 흐름</h2>
+<p>위에서 언급한 바와 같이, 문서 제공자 데이터 모델은 일반적인
+파일 계층을 기반으로 합니다. 그러나, 데이터를 물리적으로 저장하는 방식은 마음대로 선택할 수 있습니다. 다만
+{@link android.provider.DocumentsProvider} API를 통해 액세스할 수 있기만 하면 됩니다.
+예를 들어, 데이터를 저장하기 위해 태그 기반 클라우드 저장소를 사용해도 됩니다.</p>
+
+<p>그림 2는 사진 앱이 SAF를 사용하여 저장된 데이터에 액세스할 수 있는 방법을
+예시로 나타낸 것입니다.</p>
+<p><img src="{@docRoot}images/providers/storage_dataflow.png" alt="app" /></p>
+
+<p class="img-caption"><strong>그림 2.</strong> 저장소 액세스 프레임워크 흐름</p>
+
+<p>다음 내용을 참고하십시오.</p>
+<ul>
+
+<li>SAF에서는 제공자와 클라이언트가 직접 상호 작용하지 않습니다.
+ 클라이언트가 파일과 상호 작용하기 위한 권한을 요청합니다(다시 말해,
+파일을 읽고, 편집하고 생성 또는 삭제할 권한을 말합니다).</li>
+
+<li>상호 작용은 애플리케이션(이 예시에서는 주어진 사진 앱)이 인텐트
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 또는 {@link android.content.Intent#ACTION_CREATE_DOCUMENT}를 실행시키면 시작합니다. 이 인텐트에는
+기준을 한층 더 정밀하게 하기 위한 필터가 포함될 수 있습니다. 예를 들어, "열 수 있는 파일 중에서
+'이미지' MIME 유형을 가진 파일을 모두 주세요"라고 할 수 있습니다.</li>
+
+<li>인텐트가 실행되면 시스템 선택기가 각각의 등록된 제공자로 이동하여 사용자에게
+일치하는 콘텐츠 루트를 보여줍니다.</li>
+
+<li>선택기는 사용자에게 문서에 액세스하는 데 쓰는 표준 인터페이스를 부여합니다. 이는
+기본 문서 제공자 사이에 큰 차이가 있더라도 무관합니다. 예를 들어, 그림 2는
+Google Drive 제공자, USB 제공자와 클라우드 제공자를 나타낸 것입니다.</li>
+</ul>
+
+<p>그림 3은 이미지를 검색 중인 사용자가 Google Drive 계정을 선택한
+선택기를 나타낸 것입니다.</p>
+
+<p><img src="{@docRoot}images/providers/storage_picker.png" width="340" alt="picker" style="border:2px solid #ddd" /></p>
+
+<p class="img-caption"><strong>그림 3.</strong> 선택기</p>
+
+<p>사용자가 Google Drive를 선택하면 이미지가 그림 4에 나타난 것처럼
+표시됩니다. 그때부터 사용자는 제공자와 클라이언트 앱이 지원하는 방식이라면 어떤 식으로든
+이들 이미지와 상호 작용할 수 있게 됩니다.
+
+<p><img src="{@docRoot}images/providers/storage_photos.png" width="340" alt="picker" style="border:2px solid #ddd" /></p>
+
+<p class="img-caption"><strong>그림 4.</strong> 이미지</p>
+
+<h2 id="client">클라이언트 앱 작성</h2>
+
+<p>Android 4.3 이하에서는 앱이 또 다른 앱에서 파일을 검색할 수 있도록 하려면
+ {@link android.content.Intent#ACTION_PICK}
+ 또는 {@link android.content.Intent#ACTION_GET_CONTENT}와 같은 인텐트를 호출해야만 했습니다. 그런 다음
+파일을 선택할 앱을 하나 선택하고, 선택한 앱이 사용자 인터페이스를 제공하여야 사용자가
+이용 가능한 파일 중에서 탐색하고 선택할 수 있었습니다. </p>
+
+<p>Android 4.4 이상에는
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 인텐트를 사용할 수 있다는 추가 옵션이 있습니다.
+이는 시스템이 제어하는 선택기를 표시하여 사용자가 다른 앱에서 이용할 수 있게 만든 파일을
+모두 탐색할 수 있게 해줍니다. 이 하나의 UI로부터
+사용자는 지원되는 모든 앱에서 파일을 선택할 수 있는 것입니다.</p>
+
+<p>{@link android.content.Intent#ACTION_OPEN_DOCUMENT}는
+{@link android.content.Intent#ACTION_GET_CONTENT}를
+대체할 목적으로 만들어진 것이 아닙니다. 어느 것을 사용해야 할지는 각자의 앱에 필요한 것이 무엇인지에 좌우됩니다.</p>
+
+<ul>
+<li>앱이 단순히 데이터를 읽고/가져오기만을 바란다면
+{@link android.content.Intent#ACTION_GET_CONTENT}를 사용하십시오.
+이 방식을 사용하면 앱은 이미지 파일과 같은 데이터 사본을 가져오게 됩니다.</li>
+
+<li>앱이 문서 제공자가 보유한 문서에 장기적, 영구적 액세스 권한을 가지기를 바라는 경우
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT}를 사용하십시오.
+ 일례로 사용자들에게 문서 제공자에 저장된 이미지를 편집할 수 있게 해주는
+사진 편집 앱을 들 수 있겠습니다. </li>
+
+</ul>
+
+
+<p>이 섹션에서는
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 및
+{@link android.content.Intent#ACTION_CREATE_DOCUMENT} 인텐트를 근거로 클라이언트 앱을 작성하는 방법을 설명합니다.</p>
+
+
+<h3 id="search">문서 검색</h3>
+
+<p>
+다음 조각에서는 {@link android.content.Intent#ACTION_OPEN_DOCUMENT}를
+사용하여 이미지 파일이 들어 있는 문서 제공자를
+검색합니다.</p>
+
+<pre>private static final int READ_REQUEST_CODE = 42;
+...
+/**
+ * Fires an intent to spin up the &quot;file chooser&quot; UI and select an image.
+ */
+public void performFileSearch() {
+
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
+ // browser.
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as a
+ // file (as opposed to a list of contacts or timezones)
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Filter to show only images, using the image MIME data type.
+ // If one wanted to search for ogg vorbis files, the type would be &quot;audio/ogg&quot;.
+ // To search for all documents available via installed storage providers,
+ // it would be &quot;*/*&quot;.
+ intent.setType(&quot;image/*&quot;);
+
+ startActivityForResult(intent, READ_REQUEST_CODE);
+}</pre>
+
+<p>다음 내용을 참고하십시오.</p>
+<ul>
+<li>앱이 {@link android.content.Intent#ACTION_OPEN_DOCUMENT}
+ 인텐트를 실행시키면 이는 일치하는 문서 제공자를 모두 표시하는 선택기를 시작합니다.</li>
+
+<li>{@link android.content.Intent#CATEGORY_OPENABLE} 카테고리를
+인텐트에 추가하면 결과를 필터링하여 이미지 파일 등 열 수 있는 문서만 표시합니다.</li>
+
+<li>{@code intent.setType("image/*")} 문으로 한층 더 필터링을 수행하여
+MIME 데이터 유형이 이미지인 문서만 표시하도록 합니다.</li>
+</ul>
+
+<h3 id="results">결과 처리</h3>
+
+<p>사용자가 선택기에서 문서를 선택하면
+{@link android.app.Activity#onActivityResult onActivityResult()}가 호출됩니다.
+선택한 문서를 가리키는 URI는 {@code resultData}
+매개변수 안에 들어있습니다. 이 URI를 {@link android.content.Intent#getData getData()}를 사용하여 추출합니다.
+일단 이것을 가지게 되면 이를 사용하여 사용자가 원하는 문서를 검색하면 됩니다. 예:
+</p>
+
+<pre>&#64;Override
+public void onActivityResult(int requestCode, int resultCode,
+ Intent resultData) {
+
+ // The ACTION_OPEN_DOCUMENT intent was sent with the request code
+ // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
+ // response to some other intent, and the code below shouldn't run at all.
+
+ if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ // The document selected by the user won't be returned in the intent.
+ // Instead, a URI to that document will be contained in the return intent
+ // provided to this method as a parameter.
+ // Pull that URI using resultData.getData().
+ Uri uri = null;
+ if (resultData != null) {
+ uri = resultData.getData();
+ Log.i(TAG, "Uri: " + uri.toString());
+ showImage(uri);
+ }
+ }
+}
+</pre>
+
+<h3 id="metadata">문서 메타데이터 살펴보기</h3>
+
+<p>문서의 URI를 얻은 다음에는 그 문서의 메타데이터에 액세스할 수 있습니다. 이
+조각은 해당 URI가 나타내는 문서의 메타데이터를 가져와 다음과 같이 기록합니다.</p>
+
+<pre>public void dumpImageMetaData(Uri uri) {
+
+ // The query, since it only applies to a single document, will only return
+ // one row. There's no need to filter, sort, or select fields, since we want
+ // all fields for one document.
+ Cursor cursor = getActivity().getContentResolver()
+ .query(uri, null, null, null, null, null);
+
+ try {
+ // moveToFirst() returns false if the cursor has 0 rows. Very handy for
+ // &quot;if there's anything to look at, look at it&quot; conditionals.
+ if (cursor != null &amp;&amp; cursor.moveToFirst()) {
+
+ // Note it's called &quot;Display Name&quot;. This is
+ // provider-specific, and might not necessarily be the file name.
+ String displayName = cursor.getString(
+ cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
+ Log.i(TAG, &quot;Display Name: &quot; + displayName);
+
+ int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
+ // If the size is unknown, the value stored is null. But since an
+ // int can't be null in Java, the behavior is implementation-specific,
+ // which is just a fancy term for &quot;unpredictable&quot;. So as
+ // a rule, check if it's null before assigning to an int. This will
+ // happen often: The storage API allows for remote files, whose
+ // size might not be locally known.
+ String size = null;
+ if (!cursor.isNull(sizeIndex)) {
+ // Technically the column stores an int, but cursor.getString()
+ // will do the conversion automatically.
+ size = cursor.getString(sizeIndex);
+ } else {
+ size = &quot;Unknown&quot;;
+ }
+ Log.i(TAG, &quot;Size: &quot; + size);
+ }
+ } finally {
+ cursor.close();
+ }
+}
+</pre>
+
+<h3 id="open-client">문서 열기</h3>
+
+<p>문서의 URI를 얻은 다음에는 문서를 열 수도 있고 원하는 대로 무엇이든
+할 수 있습니다.</p>
+
+<h4>비트맵</h4>
+
+<p>다음은 {@link android.graphics.Bitmap}을 여는 방법을 예시로 나타낸 것입니다.</p>
+
+<pre>private Bitmap getBitmapFromUri(Uri uri) throws IOException {
+ ParcelFileDescriptor parcelFileDescriptor =
+ getContentResolver().openFileDescriptor(uri, "r");
+ FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
+ Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
+ parcelFileDescriptor.close();
+ return image;
+}
+</pre>
+
+<p>이 작업을 UI 스레드에서 해서는 안 된다는 점을 유의하십시오. 이것은 배경에서 하되,
+{@link android.os.AsyncTask}를 사용합니다. 비트맵을 열고 나면 이를
+{@link android.widget.ImageView}로 표시할 수 있습니다.
+</p>
+
+<h4>InputStream 가져오기</h4>
+
+<p>다음은 URI에서 {@link java.io.InputStream}을 가져오는 방법을 예시로 나타낸 것입니다. 이 조각에서
+파일의 줄이 문자열로 읽히고 있습니다.</p>
+
+<pre>private String readTextFromUri(Uri uri) throws IOException {
+ InputStream inputStream = getContentResolver().openInputStream(uri);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ inputStream));
+ StringBuilder stringBuilder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ stringBuilder.append(line);
+ }
+ fileInputStream.close();
+ parcelFileDescriptor.close();
+ return stringBuilder.toString();
+}
+</pre>
+
+<h3 id="create">새 문서 생성하기</h3>
+
+<p>개발자의 앱은 문서 제공자에서 새 문서를 생성할 수 있습니다. 이때
+{@link android.content.Intent#ACTION_CREATE_DOCUMENT}
+ 인텐트를 사용하면 됩니다. 파일을 생성하려면 인텐트에 MIME 유형과 파일 이름을 부여하고,
+고유한 요청 코드로 이를 시작하면 됩니다. 나머지는 여러분 대신 알아서 해드립니다.</p>
+
+
+<pre>
+// Here are some examples of how you might call this method.
+// The first parameter is the MIME type, and the second parameter is the name
+// of the file you are creating:
+//
+// createFile("text/plain", "foobar.txt");
+// createFile("image/png", "mypicture.png");
+
+// Unique request code.
+private static final int WRITE_REQUEST_CODE = 43;
+...
+private void createFile(String mimeType, String fileName) {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as
+ // a file (as opposed to a list of contacts or timezones).
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Create a file with the requested MIME type.
+ intent.setType(mimeType);
+ intent.putExtra(Intent.EXTRA_TITLE, fileName);
+ startActivityForResult(intent, WRITE_REQUEST_CODE);
+}
+</pre>
+
+<p>새 문서를 생성하고 나면
+{@link android.app.Activity#onActivityResult onActivityResult()}에서 URI를 가져와 거기에 계속해서
+쓸 수 있습니다.</p>
+
+<h3 id="delete">문서 삭제하기</h3>
+
+<p>어느 문서에 대한 URI가 있고 해당 문서의
+{@link android.provider.DocumentsContract.Document#COLUMN_FLAGS Document.COLUMN_FLAGS}
+에
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE SUPPORTS_DELETE}가 들어 있는 경우,
+해당 문서를 삭제할 수 있습니다. 예:</p>
+
+<pre>
+DocumentsContract.deleteDocument(getContentResolver(), uri);
+</pre>
+
+<h3 id="edit">문서 편집하기</h3>
+
+<p>준비된 텍스트 문서를 편집하는 데 SAF를 사용할 수 있습니다.
+이 조각은
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 인텐트를 실행하며
+{@link android.content.Intent#CATEGORY_OPENABLE} 카테고리를 사용해
+열 수 있는 문서만 표시하도록 합니다. 이것을 한층 더 필터링하여 텍스트 파일만 표시하게 하려면 다음과 같이 합니다.</p>
+
+<pre>
+private static final int EDIT_REQUEST_CODE = 44;
+/**
+ * Open a file for writing and append some text to it.
+ */
+ private void editDocument() {
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's
+ // file browser.
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as a
+ // file (as opposed to a list of contacts or timezones).
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Filter to show only text files.
+ intent.setType(&quot;text/plain&quot;);
+
+ startActivityForResult(intent, EDIT_REQUEST_CODE);
+}
+</pre>
+
+<p>다음으로, {@link android.app.Activity#onActivityResult onActivityResult()}
+(<a href="#results">결과 처리</a> 참조)에서 코드를 호출하여 편집 작업을 수행하도록 하면 됩니다.
+다음 조각은 {@link android.content.ContentResolver}에서 {@link java.io.FileOutputStream}
+을 가져온 것입니다. 이것은 기본적으로 "쓰기" 모드를 사용합니다.
+필요한 최소 수량의 액세스만을 요청하는 것이 가장 좋으니 쓰기만 필요하다면
+읽기/쓰기를 요청하지 마십시오.</p>
+
+<pre>private void alterDocument(Uri uri) {
+ try {
+ ParcelFileDescriptor pfd = getActivity().getContentResolver().
+ openFileDescriptor(uri, "w");
+ FileOutputStream fileOutputStream =
+ new FileOutputStream(pfd.getFileDescriptor());
+ fileOutputStream.write(("Overwritten by MyCloud at " +
+ System.currentTimeMillis() + "\n").getBytes());
+ // Let the document provider know you're done by closing the stream.
+ fileOutputStream.close();
+ pfd.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}</pre>
+
+<h3 id="permissions">권한 유지</h3>
+
+<p>앱이 읽기 또는 쓰기 작업에 대한 파일을 열면 시스템이 앱에 해당 파일에 대한 URI 권한 허가를
+부여합니다. 이것은 사용자의 장치를 다시 시작할 때까지 유지됩니다.
+하지만 만일 앱이 이미지 편집 앱이고, 사용자가 여러분의 앱에서 바로 편집한 5개의 이미지에
+액세스할 수 있도록 하고자 한다고 가정해봅시다. 사용자의 기기가 재시작되면
+여러분이 사용자에게 시스템 선택기를 다시 보내 해당 파일을 검색하도록 해야 할 텐데,
+이것은 물론 이상적인 것과는 거리가 멉니다.</p>
+
+<p>이런 일이 일어나지 않도록 방지하기 위해 시스템이 앱에 부여한 권한을 유지할 수 있습니다.
+여러분의 앱은 시스템이 제공하는 유지 가능한 URI 권한 허가를
+효율적으로 "받아들입니다". 이렇게 하면 사용자가 여러분의 앱을 통해 파일에 지속적인 액세스 권한을 가질 수 있으며,
+이는 기기가 다시 시작되더라도 관계 없습니다.</p>
+
+
+<pre>final int takeFlags = intent.getFlags()
+ &amp; (Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+// Check for the freshest data.
+getContentResolver().takePersistableUriPermission(uri, takeFlags);</pre>
+
+<p>마지막 한 단계가 남았습니다. 여러분의 앱이 액세스한 가장 최근의 URI를
+저장해두었을 수 있지만, 이는 더 이상 유효하지 않을 수 있습니다. 또 다른 앱이 문서를
+삭제하거나 수정했을 수 있기 때문입니다. 따라서, 항상
+{@code getContentResolver().takePersistableUriPermission()}을
+호출하여 최신 데이터를 확인해야 합니다.</p>
+
+<h2 id="custom">사용자 지정 문서 제공자 작성하기</h2>
+
+<p>
+파일용 저장소 서비스를 제공하는 앱을 개발 중인 경우(예를 들어
+클라우드 저장 서비스 등), SAF를 통해 파일을 사용할 수 있도록 하려면 사용자 지정 문서 제공자를
+작성하면 됩니다. 이 섹션에서는 이렇게 하는 방법을 설명합니다.
+</p>
+
+
+<h3 id="manifest">매니페스트</h3>
+
+<p>사용자 지정 문서 제공자를 구현하려면 애플리케이션의 매니페스트에 다음과 같은 항목을
+추가하십시오.</p>
+<ul>
+
+<li>API 레벨 19 이상의 대상.</li>
+
+<li>사용자 지정 저장소 제공자를 선언하는 <code>&lt;provider&gt;</code>
+요소. </li>
+
+<li>제공자의 이름은 그 클래스 이름이며 여기에 패키지 이름도 포함됩니다.
+예: <code>com.example.android.storageprovider.MyCloudProvider</code></li>
+
+<li>권한의 이름, 이는 패키지 이름과 같으며(이 예시에서는
+<code>com.example.android.storageprovider</code>)여기에 콘텐츠 제공자 유형을 더합니다
+(<code>documents</code>). 예: {@code com.example.android.storageprovider.documents}</li>
+
+<li><code>android:exported</code> 속성을 <code>&quot;true&quot;</code>로 설정.
+제공자를 내보내 다른 앱이 볼 수 있도록 해야 합니다.</li>
+
+<li><code>android:grantUriPermissions</code> 속성을
+<code>&quot;true&quot;</code>로 설정. 이렇게 설정하면 시스템이 여러분의 제공자 안에 있는 콘텐츠에 액세스하도록 다른 앱에
+권한을 허가할 수 있게 해줍니다. 특정 문서에 대한 권한 부여를 유지하는 방법에 대한 논의는
+<a href="#permissions">권한 유지</a>를 참조하십시오.</li>
+
+<li>{@code MANAGE_DOCUMENTS} 권한. 기본적으로 제공자는 누구나 이용할 수 있습니다.
+ 이 권한을 추가하면 여러분의 제공자를 시스템에 제한하게 됩니다.
+이 제한은 보안상 매우 중요합니다.</li>
+
+<li>{@code android:enabled} 속성을 리소스 파일에서 정의한 부울 값으로
+설정합니다. 이 속성의 목적은 Android 4.3 이하에서 실행되는 기기에서 제공자를 비활성화하는 데 있습니다.
+예를 들어 {@code android:enabled="@bool/atLeastKitKat"} 등입니다. 이 속성을
+매니페스트에 추가하는 것 이외에도 다음과 같은 작업을 해야 합니다.
+<ul>
+<li>{@code res/values/} 아래의 {@code bool.xml} 리소스 파일에
+이 라인을 추가합니다. <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;false&lt;/bool&gt;</pre></li>
+
+<li>{@code res/values-v19/} 아래의 {@code bool.xml} 리소스 파일에
+이 라인을 추가합니다. <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;true&lt;/bool&gt;</pre></li>
+</ul></li>
+
+<li>
+{@code android.content.action.DOCUMENTS_PROVIDER} 동작을 포함한 인텐트 필터가 있어야
+시스템이 제공자를 검색할 때 여러분의 제공자가 선택기에 나타날 수 있습니다.</li>
+
+</ul>
+<p>다음은 제공자를 포함한 샘플 매니페스트에서 발췌한 것입니다.</p>
+
+<pre>&lt;manifest... &gt;
+ ...
+ &lt;uses-sdk
+ android:minSdkVersion=&quot;19&quot;
+ android:targetSdkVersion=&quot;19&quot; /&gt;
+ ....
+ &lt;provider
+ android:name=&quot;com.example.android.storageprovider.MyCloudProvider&quot;
+ android:authorities=&quot;com.example.android.storageprovider.documents&quot;
+ android:grantUriPermissions=&quot;true&quot;
+ android:exported=&quot;true&quot;
+ android:permission=&quot;android.permission.MANAGE_DOCUMENTS&quot;
+ android:enabled=&quot;&#64;bool/atLeastKitKat&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.content.action.DOCUMENTS_PROVIDER&quot; /&gt;
+ &lt;/intent-filter&gt;
+ &lt;/provider&gt;
+ &lt;/application&gt;
+
+&lt;/manifest&gt;</pre>
+
+<h4 id="43">Android 4.3 이하에서 실행되는 기기 지원</h4>
+
+<p>
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} 인텐트는
+Android 4.4 이상에서 실행되는 기기에서만 사용할 수 있습니다.
+애플리케이션이 {@link android.content.Intent#ACTION_GET_CONTENT}를 지원하도록 하여
+Android 4.3 이하에서 실행되는 기기에도 적용되도록 하려면 Android 4.4 이상에서 실행되는 기기용 매니페스트에 있는
+{@link android.content.Intent#ACTION_GET_CONTENT}
+ 인텐트 필터를 비활성화해야 합니다.
+문서 제공자와 {@link android.content.Intent#ACTION_GET_CONTENT}는 상호 배타적인 것으로
+간주해야 합니다. 둘을 모두 동시에 지원하는 경우, 앱이 시스템 선택기 UI에
+두 번 나타나 저장된 데이터에 액세스할 두 가지 서로 다른 방법을 제안하게 됩니다.
+ 이렇게 되면 사용자에게 혼동을 주게 되겠죠.</p>
+
+<p>다음은 Android 버전 4.4 이상에서 실행되는 기기용
+{@link android.content.Intent#ACTION_GET_CONTENT} 인텐트 필터를
+비활성화하는 데 권장되는 방법입니다.</p>
+
+<ol>
+<li>{@code res/values/} 아래의 {@code bool.xml} 리소스 파일에
+이 라인을 추가합니다. <pre>&lt;bool name=&quot;atMostJellyBeanMR2&quot;&gt;true&lt;/bool&gt;</pre></li>
+
+<li>{@code res/values-v19/} 아래의 {@code bool.xml} 리소스 파일에
+이 라인을 추가합니다. <pre>&lt;bool name=&quot;atMostJellyBeanMR2&quot;&gt;false&lt;/bool&gt;</pre></li>
+
+<li>
+<a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">액티비티
+별칭</a>을 추가하여 버전 4.4(API 레벨 19) 이상을 대상으로 한 {@link android.content.Intent#ACTION_GET_CONTENT}
+인텐트 필터를 비활성화합니다. 예:
+
+<pre>
+&lt;!-- This activity alias is added so that GET_CONTENT intent-filter
+ can be disabled for builds on API level 19 and higher. --&gt;
+&lt;activity-alias android:name=&quot;com.android.example.app.MyPicker&quot;
+ android:targetActivity=&quot;com.android.example.app.MyActivity&quot;
+ ...
+ android:enabled=&quot;@bool/atMostJellyBeanMR2&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.GET_CONTENT&quot; /&gt;
+ &lt;category android:name=&quot;android.intent.category.OPENABLE&quot; /&gt;
+ &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
+ &lt;data android:mimeType=&quot;image/*&quot; /&gt;
+ &lt;data android:mimeType=&quot;video/*&quot; /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity-alias&gt;
+</pre>
+</li>
+</ol>
+<h3 id="contract">계약</h3>
+
+<p>사용자 지정 제공자를 작성할 때면 일반적으로 수반되는 작업 중 하나가
+계약 클래스를 구현하는 것입니다. 이는
+<a href="{@docRoot}guide/topics/providers/content-provider-creating.html#ContractClass">
+콘텐츠 제공자</a> 개발자 가이드에서 설명한 것과 같습니다. 계약 클래스는 {@code public final} 클래스로,
+이 안에 URI에 대한 상수 정의, 열 이름, MIME 유형 및 제공자에 관련된
+다른 메타 데이터가 들어 있습니다. SAF가
+이와 같은 계약 클래스를 대신 제공해주므로 직접 쓰지 않아도
+됩니다.</p>
+
+<ul>
+ <li>{@link android.provider.DocumentsContract.Document}</li>
+ <li>{@link android.provider.DocumentsContract.Root}</li>
+</ul>
+
+<p>예를 들어 다음은 여러분의 문서 제공자가 문서 또는 루트에 대해 쿼리된 경우
+커서로 반환할 수 있는 열을 나타낸 것입니다.</p>
+
+<pre>private static final String[] DEFAULT_ROOT_PROJECTION =
+ new String[]{Root.COLUMN_ROOT_ID, Root.COLUMN_MIME_TYPES,
+ Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
+ Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
+ Root.COLUMN_AVAILABLE_BYTES,};
+private static final String[] DEFAULT_DOCUMENT_PROJECTION = new
+ String[]{Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE,
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED,
+ Document.COLUMN_FLAGS, Document.COLUMN_SIZE,};
+</pre>
+
+<h3 id="subclass">하위 클래스 DocumentsProvider</h3>
+
+<p>사용자 지정 문서 제공자를 작성하기 위한 다음 단계는
+추상 클래스 {@link android.provider.DocumentsProvider}를 하위 클래스로 만드는 것입니다. 최소한 다음과 같은 메서드를 구현해야 합니다.
+</p>
+
+<ul>
+<li>{@link android.provider.DocumentsProvider#queryRoots queryRoots()}</li>
+
+<li>{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}</li>
+
+<li>{@link android.provider.DocumentsProvider#queryDocument queryDocument()}</li>
+
+<li>{@link android.provider.DocumentsProvider#openDocument openDocument()}</li>
+</ul>
+
+<p>꼭 구현해야만 하는 메서드는 이들뿐이지만, 개발자 여러분이 구현하고자 하는 메서드는 이보다
+훨씬 많을 수도 있습니다. 자세한 내용은{@link android.provider.DocumentsProvider}
+를 참조하십시오.</p>
+
+<h4 id="queryRoots">QueryRoots 구현</h4>
+
+<p>{@link android.provider.DocumentsProvider#queryRoots
+queryRoots()} 구현은 반드시 {@link android.database.Cursor}를 반환해야 하며,
+이는 문서 제공자의 모든 루트 디렉터리를 가리켜야 합니다. 이때
+{@link android.provider.DocumentsContract.Root}에서 정의한 열을 사용합니다.</p>
+
+<p>다음 조각에서 {@code projection} 매개변수는
+발신자가 돌려받고자 하는 특정 필드를 나타냅니다. 이 조각은 새 커서를 생성하며
+그에 하나의 행을 추가합니다. 하나의 루트,
+다운로드 또는 이미지와 같은 최상위 레벨 디렉터리가 해당됩니다. 대부분의 제공자에는 루트가 하나뿐입니다. 하나 이상이 있을 수도 있습니다.
+예를 들어 사용자 계정이 여러 개인 경우가 있습니다. 그런 경우에는 커서에 두 번째 행을
+추가하면 됩니다.</p>
+
+<pre>
+&#64;Override
+public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+
+ // Create a cursor with either the requested fields, or the default
+ // projection if "projection" is null.
+ final MatrixCursor result =
+ new MatrixCursor(resolveRootProjection(projection));
+
+ // If user is not logged in, return an empty root cursor. This removes our
+ // provider from the list entirely.
+ if (!isUserLoggedIn()) {
+ return result;
+ }
+
+ // It's possible to have multiple roots (e.g. for multiple accounts in the
+ // same app) -- just add multiple cursor rows.
+ // Construct one row for a root called &quot;MyCloud&quot;.
+ final MatrixCursor.RowBuilder row = result.newRow();
+ row.add(Root.COLUMN_ROOT_ID, ROOT);
+ row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary));
+
+ // FLAG_SUPPORTS_CREATE means at least one directory under the root supports
+ // creating documents. FLAG_SUPPORTS_RECENTS means your application's most
+ // recently used documents will show up in the &quot;Recents&quot; category.
+ // FLAG_SUPPORTS_SEARCH allows users to search all documents the application
+ // shares.
+ row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE |
+ Root.FLAG_SUPPORTS_RECENTS |
+ Root.FLAG_SUPPORTS_SEARCH);
+
+ // COLUMN_TITLE is the root title (e.g. Gallery, Drive).
+ row.add(Root.COLUMN_TITLE, getContext().getString(R.string.title));
+
+ // This document id cannot change once it's shared.
+ row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir));
+
+ // The child MIME types are used to filter the roots and only present to the
+ // user roots that contain the desired type somewhere in their file hierarchy.
+ row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir));
+ row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace());
+ row.add(Root.COLUMN_ICON, R.drawable.ic_launcher);
+
+ return result;
+}</pre>
+
+<h4 id="queryChildDocuments">QueryChildDocuments 구현</h4>
+
+<p>
+{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}
+ 구현은 반드시 {@link android.database.Cursor}를 반환해야 하며,
+이는 지정된 디렉터리 내의 모든 파일을 가리켜야 합니다. 이때
+{@link android.provider.DocumentsContract.Document}에서 정의한 열을 사용합니다.</p>
+
+<p>이 메서드는 선택기 UI에서 애플리케이션 루트를 선택하는 경우 호출됩니다.
+이는 해당 루트 아래 디렉터리의 하위 문서를 가져옵니다. 이것은 루트에서뿐만 아니라 파일 계층의 어느 레벨에서나
+호출할 수 있습니다. 이 조각은 요청한 열로 새 커서를 만든 다음,
+상위 디렉터리에 있는 모든 직속 하위에 대한 정보를 커서에 추가합니다.
+하위는 이미지, 또 다른 디렉터리가 될 수도 있고
+어느 파일이라도 될 수 있습니다.</p>
+
+<pre>&#64;Override
+public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
+ String sortOrder) throws FileNotFoundException {
+
+ final MatrixCursor result = new
+ MatrixCursor(resolveDocumentProjection(projection));
+ final File parent = getFileForDocId(parentDocumentId);
+ for (File file : parent.listFiles()) {
+ // Adds the file's display name, MIME type, size, and so on.
+ includeFile(result, null, file);
+ }
+ return result;
+}
+</pre>
+
+<h4 id="queryDocument">QueryDocuments 구현</h4>
+
+<p>
+{@link android.provider.DocumentsProvider#queryDocument queryDocument()}
+ 구현은 반드시 {@link android.database.Cursor}를 반환해야 하며,
+이는 지정된 파일을 가리켜야 합니다. 이때 {@link android.provider.DocumentsContract.Document}에서 정의한 열을 사용합니다.
+</p>
+
+<p>{@link android.provider.DocumentsProvider#queryDocument queryDocument()}
+ 메서드는
+{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}에서
+전달된 것과 같은 정보를 반환하지만, 특정한 파일에만 해당됩니다.</p>
+
+
+<pre>&#64;Override
+public Cursor queryDocument(String documentId, String[] projection) throws
+ FileNotFoundException {
+
+ // Create a cursor with the requested projection, or the default projection.
+ final MatrixCursor result = new
+ MatrixCursor(resolveDocumentProjection(projection));
+ includeFile(result, documentId, null);
+ return result;
+}
+</pre>
+
+<h4 id="openDocument">OpenDocument 구현</h4>
+
+<p>지정된 파일을 나타내는
+{@link android.os.ParcelFileDescriptor}를 반환하려면 {@link android.provider.DocumentsProvider#openDocument
+openDocument()}를 구현해야 합니다. 다른 앱들이 반환된 {@link android.os.ParcelFileDescriptor}를
+ 사용하여 데이터를 스트리밍할 수 있습니다. 시스템은 사용자가 파일을 선택하고
+클라이언트 앱이 이에 대한 액세스를 요청하면서
+{@link android.content.ContentResolver#openFileDescriptor openFileDescriptor()}를 사용할 때 이 메서드를 호출합니다.
+예를 들면 다음과 같습니다.</p>
+
+<pre>&#64;Override
+public ParcelFileDescriptor openDocument(final String documentId,
+ final String mode,
+ CancellationSignal signal) throws
+ FileNotFoundException {
+ Log.v(TAG, &quot;openDocument, mode: &quot; + mode);
+ // It's OK to do network operations in this method to download the document,
+ // as long as you periodically check the CancellationSignal. If you have an
+ // extremely large file to transfer from the network, a better solution may
+ // be pipes or sockets (see ParcelFileDescriptor for helper methods).
+
+ final File file = getFileForDocId(documentId);
+
+ final boolean isWrite = (mode.indexOf('w') != -1);
+ if(isWrite) {
+ // Attach a close listener if the document is opened in write mode.
+ try {
+ Handler handler = new Handler(getContext().getMainLooper());
+ return ParcelFileDescriptor.open(file, accessMode, handler,
+ new ParcelFileDescriptor.OnCloseListener() {
+ &#64;Override
+ public void onClose(IOException e) {
+
+ // Update the file with the cloud server. The client is done
+ // writing.
+ Log.i(TAG, &quot;A file with id &quot; +
+ documentId + &quot; has been closed!
+ Time to &quot; +
+ &quot;update the server.&quot;);
+ }
+
+ });
+ } catch (IOException e) {
+ throw new FileNotFoundException(&quot;Failed to open document with id &quot;
+ + documentId + &quot; and mode &quot; + mode);
+ }
+ } else {
+ return ParcelFileDescriptor.open(file, accessMode);
+ }
+}
+</pre>
+
+<h3 id="security">보안</h3>
+
+<p>여러분의 문서 제공자가 암호로 보호된 클라우드 저장소 서비스이고
+여러분은 사용자가 파일을 공유하기 전에 우선 로그인부터 하도록 확실히 해두고 싶다고 가정합니다.
+사용자가 로그인되지 않은 경우 앱은 어떻게 해야 합니까? 해법은
+{@link android.provider.DocumentsProvider#queryRoots
+queryRoots()} 구현에서 루트를 반환하지 않는 것입니다. 다시 말해, 텅 빈 루트 커서를 반환하는 것입니다.</p>
+
+<pre>
+public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+...
+ // If user is not logged in, return an empty root cursor. This removes our
+ // provider from the list entirely.
+ if (!isUserLoggedIn()) {
+ return result;
+}
+</pre>
+
+<p>또 다른 단계는 {@code getContentResolver().notifyChange()}를 호출하는 것입니다.
+{@link android.provider.DocumentsContract}를 기억하십니까? 이것을 사용하는 이유는
+바로 이 URI를 만들기 위해서입니다. 다음 조각은 사용자의 로그인 상태가 변경될 때마다
+시스템이 문서 제공자의 루트를 쿼리하도록 지시하고 있습니다. 사용자가 로그인되어 있지 않은 상태에서
+{@link android.provider.DocumentsProvider#queryRoots queryRoots()}를 호출하면
+위에서 나타낸 것과 같이 빈 커서를 반환합니다. 이렇게 하면 사용자가 제공자에 로그인되었을 때만
+제공자의 문서를 사용할 수 있도록 보장할 수 있습니다.</p>
+
+<pre>private void onLoginButtonClick() {
+ loginOrLogout();
+ getContentResolver().notifyChange(DocumentsContract
+ .buildRootsUri(AUTHORITY), null);
+}
+</pre> \ No newline at end of file
diff --git a/docs/html-intl/intl/ko/guide/topics/resources/accessing-resources.jd b/docs/html-intl/intl/ko/guide/topics/resources/accessing-resources.jd
new file mode 100644
index 000000000000..be9dd6bb0b20
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/resources/accessing-resources.jd
@@ -0,0 +1,337 @@
+page.title=리소스 액세스
+parent.title=애플리케이션 리소스
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>간략히 보기</h2>
+ <ul>
+ <li>리소스는 {@code R.java}의 정수를 사용하는 코드, 예를 들어
+{@code R.drawable.myimage}에서 참조할 수 있습니다.</li>
+ <li>리소스는 특수 XML 구문을 사용하는 리소스, 예를 들어 {@code
+&#64;drawable/myimage}에서 참조할 수 있습니다.</li>
+ <li>
+{@link android.content.res.Resources}의 메서드로 앱 리소스에 액세스할 수도 있습니다.</li>
+ </ul>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.content.res.Resources}</li>
+ </ol>
+
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#ResourcesFromCode">코드에서 리소스 액세스</a></li>
+ <li><a href="#ResourcesFromXml">XML에서 리소스 액세스</a>
+ <ol>
+ <li><a href="#ReferencesToThemeAttributes">스타일 속성 참조</a></li>
+ </ol>
+ </li>
+ <li><a href="#PlatformResources">플랫폼 리소스 액세스</a></li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="providing-resources.html">리소스 제공</a></li>
+ <li><a href="available-resources.html">리소스 유형</a></li>
+ </ol>
+</div>
+</div>
+
+
+
+
+<p>일단 어떤 리소스를 애플리케이션에 제공한 다음에는(<a href="providing-resources.html">리소스 제공</a>에서 논의),
+해당 리소스의 리소스 ID를 참조함으로써 이를 적용할 수 있습니다. 모든 리소스 ID는
+{@code aapt} 도구가 자동으로 생성하는 프로젝트의 {@code R} 클래스에서 정의됩니다.</p>
+
+<p>애플리케이션이 컴파일링되면, {@code aapt}가 {@code R} 클래스를 생성하며, 이 클래스 안에 {@code
+res/} 디렉터리에 있는 모든 리소스의
+리소스 ID가 들어있습니다. 각 리소스 유형에는 {@code R} 하위 클래스가 있고(예: 모든 드로어블 리소스에 대한
+{@code R.drawable}), 해당 유형의 각 리소스에는 정적
+정수가 있습니다(예: {@code R.drawable.icon}). 이 정수가
+리소스를 검색하는 데 사용할 수 있는 리소스 ID입니다.</p>
+
+<p>{@code R} 클래스가 리소스 ID가 지정되는 곳이기는 하지만, 리소스 ID를 찾기 위해
+이곳을 볼 필요는 전혀 없습니다. 하나의 리소스 ID는 항상 다음과 같이 구성됩니다.</p>
+<ul>
+ <li><em>리소스 유형</em>: 각 리소스는 "유형"으로 그룹화됩니다. 예: {@code
+string}, {@code drawable} 및 {@code layout} 다양한 유형에 관한 자세한 정보는 <a href="available-resources.html">리소스 유형</a>을 참조하십시오.
+ </li>
+ <li><em>리소스 이름</em>:
+리소스가 단순 값(예: 문자열 등)일 경우,
+확장자를 제외한 파일 이름이나 XML {@code android:name} 속성 값 중 하나입니다.</li>
+</ul>
+
+<p>리소스에 액세스하는 방법은 두 가지가 있습니다.</p>
+<ul>
+ <li><strong>코드 내부에서:</strong> {@code R}
+클래스의 하위 클래스에서 정적 정수를 사용합니다. 예:
+ <pre class="classic no-pretty-print">R.string.hello</pre>
+ <p>{@code string}은 리소스 유형이고 {@code hello}는 리소스 이름입니다. 리소스 ID를 이 형식으로 제공하면 리소스에 액세스할 수 있는
+Android API가 많습니다.
+<a href="#ResourcesFromCode">코드 내 리소스 액세스</a>를 참조하십시오.</p>
+ </li>
+ <li><strong>XML 내부에서:</strong> {@code R} 클래스에서 정의된
+리소스 ID에 상응하기도 하는 특수 XML 구문을 사용합니다. 예:
+ <pre class="classic no-pretty-print">&#64;string/hello</pre>
+ <p>{@code string}은 리소스 유형이고 {@code hello}는 리소스 이름입니다. 이
+구문은 리소스로 값을 제공할 것으로 예상되는 어느 곳에서나 XML 리소스 형태로 사용할 수 있습니다. <a href="#ResourcesFromXml">XML에서 리소스 액세스</a>를 참조하십시오.</p>
+ </li>
+</ul>
+
+
+
+<h2 id="ResourcesFromCode">코드 내 리소스 액세스 </h2>
+
+<p>리소스 ID를 메서드 매개변수로 전달하면 코드 내 리소스를 사용할 수 있습니다. 예를 들어
+, {@link android.widget.ImageView}를 설정하여 {@link android.widget.ImageView#setImageResource(int) setImageResource()}를 사용하는 {@code res/drawable/myimage.png}
+리소스를 사용할 수 있습니다.</p>
+<pre>
+ImageView imageView = (ImageView) findViewById(R.id.myimageview);
+imageView.setImageResource(<strong>R.drawable.myimage</strong>);
+</pre>
+
+<p>{@link
+android.content.res.Resources}에서 메서드를 사용하는 개별 리소스를 검색할 수도 있으며, 이는
+{@link android.content.Context#getResources()}로 인스턴스를 가져올 수 있습니다.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>원본 파일에 액세스</h2>
+
+<p>흔한 일은 아니지만, 원본 파일과 디렉터리에 액세스해야 하는 경우가 있습니다. 이 경우에는
+{@code res/}에 파일을 저장하더라도 소용이 없습니다.
+{@code res/}에서 리소스를 읽는 방법은 리소스 ID를 사용하는 것뿐이기 때문입니다. 그 대신 리소스를
+{@code assets/} 디렉터리에 저장하면 됩니다.</p>
+<p>{@code assets/} 디렉터리에 저장된 파일은 리소스
+ID가 부여되지 <em>않으므로</em>, 이와 같은 리소스는 {@code R} 클래스나 XML 리소스에서 참조할 수 없습니다. 그 대신
+일반 파일 시스템처럼 {@code assets/} 디렉터리에 파일을 쿼리하고
+{@link android.content.res.AssetManager}를 사용하여 원시 데이터를 읽을 수 있습니다.</p>
+<p>하지만 필요한 것이 원시 데이터(동영상 또는 오디오 파일 등)를 읽는 능력뿐인 경우라면,
+파일을 {@code res/raw/} 디렉터리에 저장한 다음 일련의 바이트 스트림을 {@link
+android.content.res.Resources#openRawResource(int) openRawResource()}를 사용하여 읽으면 됩니다.</p>
+
+</div>
+</div>
+
+
+<h3>구문</h3>
+
+<p>다음은 코드로 리소스를 참조하는 데 쓰는 구문입니다.</p>
+
+<pre class="classic no-pretty-print">
+[<em>&lt;package_name&gt;</em>.]R.<em>&lt;resource_type&gt;</em>.<em>&lt;resource_name&gt;</em>
+</pre>
+
+<ul>
+ <li><em>{@code &lt;package_name&gt;}</em>은(는) 리소스가 위치한 패키지의 이름입니다(
+자체 패키지의 리소스를 참조할 경우에는 필요하지 않습니다).</li>
+ <li><em>{@code &lt;resource_type&gt;}</em>은(는) 해당 리소스 유형의 {@code R} 하위 클래스입니다.</li>
+ <li><em>{@code &lt;resource_name&gt;}</em>은(는) 확장자가 없는 리소스 파일 이름이거나
+XML 요소의 {@code android:name} 속성 값입니다(단순
+값의 경우).</li>
+</ul>
+<p>각 리소스 유형과 참조 방법에 관한 자세한 내용은 <a href="available-resources.html">리소스 유형</a>
+을 참조하십시오.</p>
+
+
+<h3>사용 사례</h3>
+
+<p>리소스 ID 매개변수를 허용하는 메서드가 많이 있고, {@link android.content.res.Resources}에서 메서드를
+ 사용하여 리소스를 검색할 수 있습니다. {@link android.content.Context#getResources
+Context.getResources()}로 {@link
+android.content.res.Resources}의 인스턴스를 가져올 수 있습니다.</p>
+
+
+<p>다음은 코드로 리소스에 액세스한 몇 가지 예시입니다.</p>
+
+<pre>
+// Load a background for the current screen from a drawable resource
+{@link android.app.Activity#getWindow()}.{@link
+android.view.Window#setBackgroundDrawableResource(int)
+setBackgroundDrawableResource}(<strong>R.drawable.my_background_image</strong>) ;
+
+// Set the Activity title by getting a string from the Resources object, because
+// this method requires a CharSequence rather than a resource ID
+{@link android.app.Activity#getWindow()}.{@link android.view.Window#setTitle(CharSequence)
+setTitle}(getResources().{@link android.content.res.Resources#getText(int)
+getText}(<strong>R.string.main_title</strong>));
+
+// Load a custom layout for the current screen
+{@link android.app.Activity#setContentView(int)
+setContentView}(<strong>R.layout.main_screen</strong>);
+
+// Set a slide in animation by getting an Animation from the Resources object
+mFlipper.{@link android.widget.ViewAnimator#setInAnimation(Animation)
+setInAnimation}(AnimationUtils.loadAnimation(this,
+ <strong>R.anim.hyperspace_in</strong>));
+
+// Set the text on a TextView object using a resource ID
+TextView msgTextView = (TextView) findViewById(<strong>R.id.msg</strong>);
+msgTextView.{@link android.widget.TextView#setText(int)
+setText}(<strong>R.string.hello_message</strong>);
+</pre>
+
+
+<p class="caution"><strong>주의:</strong> 손으로 {@code
+R.java} 파일을 수정해서는 안 됩니다.&mdash;이것은 프로젝트가
+컴파일되었을 때 {@code aapt} 도구가 생성한 파일입니다. 모든 변경 사항은 다음 번 컴파일에서 재정의됩니다.</p>
+
+
+
+<h2 id="ResourcesFromXml">XML에서 리소스 액세스</h2>
+
+<p>기존 리소스에 대한 참조를 사용하여
+일부 XML 속성과 요소의 값을 정의할 수 있습니다. 이 작업은 레이아웃 파일을 생성할 때 위젯에 문자열과 이미지를 제공하기 위해
+자주 하게 됩니다.</p>
+
+<p>예를 들어, 레이아웃에 {@link android.widget.Button}을 추가하면
+해당 버튼 텍스트에 <a href="string-resource.html">문자열 리소스</a>를 사용해야 합니다.</p>
+
+<pre>
+&lt;Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="<strong>@string/submit</strong>" /&gt;
+</pre>
+
+
+<h3>구문</h3>
+
+<p>다음은 XML 리소스로 리소스를 참조하는 데 쓰는 구문입니다.</p>
+
+<pre class="classic no-pretty-print">
+&#64;[<em>&lt;package_name&gt;</em>:]<em>&lt;resource_type&gt;</em>/<em>&lt;resource_name&gt;</em>
+</pre>
+
+<ul>
+ <li>{@code &lt;package_name&gt;}은(는) 리소스가 위치한 패키지의 이름입니다(
+같은 패키지의 리소스를 참조할 경우에는 필요하지 않습니다).</li>
+ <li>{@code &lt;resource_type&gt;}은(는) 해당 리소스 유형의
+{@code R} 하위 클래스입니다.</li>
+ <li>{@code &lt;resource_name&gt;}은(는) 확장자가 없는 리소스 파일 이름이거나
+XML 요소의 {@code android:name} 속성 값입니다(단순
+값의 경우).</li>
+</ul>
+
+<p>각 리소스 유형과 참조 방법에 관한 자세한 내용은 <a href="available-resources.html">리소스 유형</a>
+을 참조하십시오.</p>
+
+
+<h3>사용 사례</h3>
+
+<p>몇몇 경우에는 값에 대한 리소스를 반드시 XML로 사용해야 하지만(예: 위젯에 드로어블 이미지를
+ 적용하기 위해), 단순 값을 허용하는 곳이라면 어디서든 XML로 리소스를 사용할 수도 있습니다. 예를 들어
+, <a href="more-resources.html#Color">색상 리소스</a>와 <a href="string-resource.html">문자열 리소스</a>를 포함한 다음과 같은 리소스 파일을 가지고 있다고 합시다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;color name="opaque_red">#f00&lt;/color>
+ &lt;string name="hello">Hello!&lt;/string>
+&lt;/resources>
+</pre>
+
+<p>텍스트 색상과
+텍스트 문자열을 설정하는 데 이와 같은 리소스를 다음의 레이아웃 파일에서 사용할 수 있습니다.</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;fill_parent&quot;
+ android:textColor=&quot;<strong>&#64;color/opaque_red</strong>&quot;
+ android:text=&quot;<strong>&#64;string/hello</strong>&quot; /&gt;
+</pre>
+
+<p>이 경우, 리소스를 자체 패키지에서 가져왔으므로 리소스 참조에 패키지 이름을
+지정하지 않아도 됩니다.
+시스템 리소스를 참조하려면 패키지 이름을 포함해야 합니다. 예:</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;fill_parent&quot;
+ android:textColor=&quot;<strong>&#64;android:color/secondary_text_dark</strong>&quot;
+ android:text=&quot;&#64;string/hello&quot; /&gt;
+</pre>
+
+<p class="note"><strong>참고:</strong> 항상 문자열 리소스를 사용해야
+사용자의 애플리케이션이 다른 언어에 맞게 지역화될 수 있습니다.
+대체
+리소스(예: 지역화된 문자열) 생성에 관한 자세한 정보는 <a href="providing-resources.html#AlternativeResources">대체
+리소스 제공</a>을 참조하십시오. 다른 언어로 애플리케이션을 지역화하기 위한 전체 지침은
+<a href="localization.html">지역화</a>를 참조하십시오.</p>
+
+<p>XML의 리소스를 사용하여 별명을 생성할 수도 있습니다. 예를 들어, 드로어블 리소스이면서
+또 다른 드로어블 리소스의 별명인 것을 생성할 수 있습니다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/other_drawable" />
+</pre>
+
+<p>이것은 일견 중복되는 것처럼 들리지만, 대체 리소스를 사용할 때 매우 유용하게 쓰일 수 있습니다.
+<a href="providing-resources.html#AliasResources">별명 리소스 생성</a>에 관해 자세히 알아보십시오.</p>
+
+
+
+<h3 id="ReferencesToThemeAttributes">스타일 속성 참조</h3>
+
+<p>스타일 속성 리소스는 현재 적용된 테마의 속성 값을
+참조할 수 있게 해줍니다. 스타일 속성을 참조하면
+하드 코드로 작성된 값을 제공하는 것 대신에 UI 요소의 외관을 사용자 지정하여
+현재 테마에서 제공한 표준 변형에 맞춰 스타일링할 수 있습니다. 스타일 속성을 참조하는 것은
+기본적으로 "이 속성이 정의한 스타일을 현재 테마로 사용하라"는 말과 같습니다.</p>
+
+<p>스타일 속성을 참조하는 경우, 이름 구문은 보통
+리소스와 거의 똑같습니다. 다만 앳 기호({@code @})를 사용하는 대신 물음표({@code ?})를 사용하며,
+리소스 유형 부분이 선택 사항이라는 점만이 다릅니다. 예:</p>
+
+<pre class="classic">
+?[<em>&lt;package_name&gt;</em>:][<em>&lt;resource_type&gt;</em>/]<em>&lt;resource_name&gt;</em>
+</pre>
+
+<p>예컨대 다음은 텍스트 색상을 시스템 테마의 "기본" 텍스트 색상에
+일치하도록 설정하기 위해 속성을 참조하는 방법을 나타낸 것입니다.</p>
+
+<pre>
+&lt;EditText id=&quot;text&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;wrap_content&quot;
+ android:textColor=&quot;<strong>?android:textColorSecondary</strong>&quot;
+ android:text=&quot;&#64;string/hello_world&quot; /&gt;
+</pre>
+
+<p>여기서 {@code android:textColor} 속성이 주어진 스타일 속성의 이름을 현재 테마대로
+지정합니다. Android는 이제 {@code android:textColorSecondary}
+스타일 속성에 적용된 값을 이 위젯의 {@code android:textColor}에 대한 값으로 사용합니다. 시스템
+리소스 도구는 속성 리소스가 이 컨텍스트에서 예상된다는 것을 알기 때문에
+유형(
+<code>?android:attr/textColorSecondary</code>)을 명시적으로 선언하지 않아도 됩니다.&mdash;{@code attr} 유형은 배제해도 됩니다.</p>
+
+
+
+
+<h2 id="PlatformResources">플랫폼 리소스 액세스</h2>
+
+<p>Android에는 스타일, 테마 및 레이아웃 등 여러 가지 표준 리소스가 포함되어 있습니다.
+이와 같은 리소스에 액세스하려면
+<code>android</code> 패키지 이름으로 리소스 참조를 한정합니다. 예를 들어 Android는
+{@link android.widget.ListAdapter}의 목록 항목으로 사용할 수 있는 레이아웃 리소스를 제공합니다.</p>
+
+<pre>
+{@link android.app.ListActivity#setListAdapter(ListAdapter)
+setListAdapter}(new {@link
+android.widget.ArrayAdapter}&lt;String&gt;(this, <strong>android.R.layout.simple_list_item_1</strong>, myarray));
+</pre>
+
+<p>이 예시에서 {@link android.R.layout#simple_list_item_1}은
+{@link android.widget.ListView}의 항목에 대해 플랫폼이 정의한 레이아웃 리소스입니다. 목록 항목에 대해 나름의 레이아웃을
+만드는 대신 이것을 사용해도 됩니다. 자세한 내용은
+<a href="{@docRoot}guide/topics/ui/layout/listview.html">목록 보기</a> 개발자 가이드를 참조하십시오.</p>
+
diff --git a/docs/html-intl/intl/ko/guide/topics/resources/overview.jd b/docs/html-intl/intl/ko/guide/topics/resources/overview.jd
new file mode 100644
index 000000000000..e98a67750772
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/resources/overview.jd
@@ -0,0 +1,103 @@
+page.title=리소스 개요
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>주제</h2>
+ <ol>
+ <li><a href="providing-resources.html">리소스 제공</a></li>
+ <li><a href="accessing-resources.html">리소스 액세스</a></li>
+ <li><a href="runtime-changes.html">런타임 변경 처리</a></li>
+ <li><a href="localization.html">지역화</a></li>
+ </ol>
+
+ <h2>참조</h2>
+ <ol>
+ <li><a href="available-resources.html">리소스 유형</a></li>
+ </ol>
+</div>
+</div>
+
+
+<p>이미지나 문자열 같은 리소스는 항상 애플리케이션 코드에서
+외부화하여 독립적으로 유지해야 합니다. 리소스를 외부화하면
+다양한 언어나 화면 크기와 같은 특정 기기 구성을 지원하는
+대체 리소스를 제공할 수 있습니다. 이러한 기능은 Android 구동 장치를
+다양한 구성에서 이용하게 되면서 점점 더 중요해지고 있습니다. 여러 가지 구성에
+호환성을 제공하려면 프로젝트의
+{@code res/} 디렉터리 안에 리소스를 정리해야 합니다. 이때 여러 가지 하위 디렉터리를 사용하여 리소스를 유형과 구성
+기준으로 그룹화하면 좋습니다.</p>
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram1.png" height="167" alt="" />
+<p class="img-caption">
+<strong>그림 1.</strong> 각각 기본 레이아웃을 사용하는 서로 다른 두 개의 기기입니다
+(앱에서 대체 레이아웃을 제공하지 않습니다).</p>
+</div>
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" />
+<p class="img-caption">
+<strong>그림 2.</strong> 서로 다른 두 개의 기기로, 각각 다른 화면 크기에 맞게 제공된 서로 다른
+레이아웃을 사용하고 있습니다.</p>
+</div>
+
+<p>어떤 유형의 리소스든 애플리케이션에 맞게<em>기본값</em>과 여러
+<em>대체</em> 리소스를 지정할 수 있습니다.</p>
+<ul>
+ <li>기본 리소스는 기기 구성에 관계없이 항상 사용하거나
+기존 구성에 일치하는 대체 리소스가 없을 때
+사용합니다.</li>
+ <li>대체 리소스는 특정 구성에서 사용하기 위해 개발자가 특별히 디자인한 것을
+말합니다. 리소스 그룹을 특정 구성용으로 지정하려면,
+디렉터리 이름에 적절한 구성 한정자를 추가하십시오.</li>
+</ul>
+
+<p>예를 들어 기본 UI 레이아웃은
+{@code res/layout/} 디렉터리에 저장되어 있더라도 화면이 가로 방향일 때 사용할
+다른 레이아웃을 지정할 수도 있습니다. 이를 {@code res/layout-land/}
+디렉터리에 저장하면 됩니다. Android는
+기기의 현재 구성을 리소스 디렉터리 이름과 일치시켜서 적절한 리소스를 적용합니다.</p>
+
+<p>그림 1은 이용 가능한 대체 리소스가 없을 경우 시스템이 서로 다른 두 개의 기기에
+같은 레이아웃을 적용하는 방법을 보여줍니다. 그림 2는
+같은 애플리케이션에 큰 화면용 레이아웃 리소스를 추가한 모습을 나타낸 것입니다.</p>
+
+<p>다음 문서는 대체 리소스를 체계화하고,
+대체 리소스를 지정하고, 애플리케이션에 액세스 하는 등의 방법에 관한 완전한 지침을 제공합니다.</p>
+
+<dl>
+ <dt><strong><a href="providing-resources.html">리소스 제공</a></strong></dt>
+ <dd>앱에 포함할 수 있는 여러 가지 종류의 리소스와, 이러한 리소스를 저장하는 장소, 특정 기기 구성에 대한
+대체 리소스를 생성하는 방법입니다.</dd>
+ <dt><strong><a href="accessing-resources.html">리소스 액세스</a></strong></dt>
+ <dd>제공한 리소스를 사용하는 방법입니다. 이를 애플리케이션 코드에서 참조하거나
+다른 XML 리소스에서 참조하는 방식을 씁니다.</dd>
+ <dt><strong><a href="runtime-changes.html">런타임 변경 처리</a></strong></dt>
+ <dd>액티비티가 실행 중인 동안 발생한 구성 변경을 관리하는 방법입니다.</dd>
+ <dt><strong><a href="localization.html">지역화</a></strong></dt>
+ <dd>대체 리소스를 사용하여 애플리케이션을 지역화하는 방법에 대한 상세한 가이드입니다. 이것은 대체
+리소스를 사용하는 한 가지 방법에 불과하지만, 더 많은 사용자에게 도달하려면 매우 중요한
+방법입니다.</dd>
+ <dt><strong><a href="available-resources.html">리소스 유형</a></strong></dt>
+ <dd>개발자가 제공할 수 있는 다양한 리소스 유형의 참조로, 각각의 XML 요소,
+속성과 구문을 설명하는 것입니다. 예를 들어, 이 참조는 애플리케이션 메뉴와 드로어블 리소스,
+애니메이션에 대한 리소스를 생성하는 법을 보여줍니다.</dd>
+</dl>
+
+<!--
+<h2>Raw Assets</h2>
+
+<p>An alternative to saving files in {@code res/} is to save files in the {@code
+assets/} directory. This should only be necessary if you need direct access to original files and
+directories by name. Files saved in the {@code assets/} directory will not be given a resource
+ID, so you can't reference them through the {@code R} class or from XML resources. Instead, you can
+query data in the {@code assets/} directory like an ordinary file system, search through the
+directory and
+read raw data using {@link android.content.res.AssetManager}. For example, this can be more useful
+when dealing with textures for a game. However, if you only need to read raw data from a file
+(such as a video or audio file), then you should save files into the {@code res/raw/} directory and
+then read a stream of bytes using {@link android.content.res.Resources#openRawResource(int)}. This
+is uncommon, but if you need direct access to original files in {@code assets/}, refer to the {@link
+android.content.res.AssetManager} documentation.</p>
+-->
diff --git a/docs/html-intl/intl/ko/guide/topics/resources/providing-resources.jd b/docs/html-intl/intl/ko/guide/topics/resources/providing-resources.jd
new file mode 100644
index 000000000000..681cbb31c4fb
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/resources/providing-resources.jd
@@ -0,0 +1,1094 @@
+page.title=리소스 제공
+parent.title=애플리케이션 리소스
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>간략히 보기</h2>
+ <ul>
+ <li>{@code res/}의 여러 가지 하위 디렉터리에 속한 여러 가지 유형의 리소스</li>
+ <li>구성별 리소스 파일을 제공하는 대체 리소스</li>
+ <li>항상 기본 리소스를 포함해야 앱이 특정 기기 구성에
+좌우되지 않습니다.</li>
+ </ul>
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#ResourceTypes">리소스 유형 그룹화</a></li>
+ <li><a href="#AlternativeResources">대체 리소스 제공</a>
+ <ol>
+ <li><a href="#QualifierRules">한정자 이름 규칙</a></li>
+ <li><a href="#AliasResources">별명 리소스 생성</a></li>
+ </ol>
+ </li>
+ <li><a href="#Compatibility">리소스와 연관된 최선의 기기 호환성 제공</a></li>
+ <li><a href="#BestMatch">Android가 가장 잘 일치하는 리소스를 찾는 방법</a></li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="accessing-resources.html">리소스 액세스</a></li>
+ <li><a href="available-resources.html">리소스 유형</a></li>
+ <li><a href="{@docRoot}guide/practices/screens_support.html">다중
+화면 지원</a></li>
+ </ol>
+</div>
+</div>
+
+<p>이미지나 문자열과 같은 애플리케이션 리소스는 항상 코드에서 외부화해야 합니다.
+그래야 이들을 독립적으로 유지관리할 수 있습니다. 특정 기기 구성에 대한 대체 리소스도
+제공해야 합니다. 이것은 특별하게 명명한 리소스 디렉터리에 그룹화하는 방법을 씁니다. Android는
+런타임에 현재 구성을 근거로 적절한 리소스를 사용합니다. 예를 들어
+여러 가지 화면 크기에 따라 여러 가지 UI 레이아웃을 제공하거나 언어 설정에 따라
+각기 다른 문자열을 제공하고자 할 수 있습니다.</p>
+
+<p>애플리케이션 리소스를 외부화하면
+프로젝트 {@code R} 클래스에서 발생하는 리소스 ID로 액세스할 수 있습니다. 애플리케이션에서
+리소스를 사용하는 방법은 <a href="accessing-resources.html">리소스
+액세스</a>에서 설명합니다. 이 문서에서는 Android 프로젝트에서 리소스를 그룹화하는 방법과 특정 기기 구성에 대한
+대체 리소스를 제공하는 법을 보여드립니다.</p>
+
+
+<h2 id="ResourceTypes">리소스 유형 그룹화</h2>
+
+<p>프로젝트
+{@code res/} 디렉터리의 특정 하위 디렉터리에 각 유형의 리소스를 배치해야 합니다. 예를 들어, 다음은 간단한 프로젝트의 파일 계층입니다.</p>
+
+<pre class="classic no-pretty-print">
+MyProject/
+ src/ <span style="color:black">
+ MyActivity.java </span>
+ res/
+ drawable/ <span style="color:black">
+ graphic.png </span>
+ layout/ <span style="color:black">
+ main.xml
+ info.xml</span>
+ mipmap/ <span style="color:black">
+ icon.png </span>
+ values/ <span style="color:black">
+ strings.xml </span>
+</pre>
+
+<p>이 예시에서 {@code res/} 디렉터리가 모든 리소스(이미지 리소스, 레이아웃 리소스 두 개, 시작 관리자 아이콘용 {@code mipmap/} 디렉터리,
+ 문자열 리소스 파일)를 (하위 디렉터리에
+) 포함하는 것을 볼 수 있습니다. 리소스 디렉터리 이름은
+중요하며 표1에 설명되어 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> Mipmap 폴더를 사용하는 자세한 방법은
+<a href="{@docRoot}tools/projects/index.html#mipmap">프로젝트 관리 개요</a>를 참조하십시오.</p>
+
+<p class="table-caption" id="table1"><strong>표 1</strong>. 프로젝트
+{@code res/} 디렉터리 내부에서 지원하는 리소스 디렉터리입니다.</p>
+
+<table>
+ <tr>
+ <th scope="col">디렉터리</th>
+ <th scope="col">리소스 유형</th>
+ </tr>
+
+ <tr>
+ <td><code>animator/</code></td>
+ <td><a href="{@docRoot}guide/topics/graphics/prop-animation.html">속성
+애니메이션</a>을 정의하는 XML 파일입니다.</td>
+ </tr>
+
+ <tr>
+ <td><code>anim/</code></td>
+ <td><a href="{@docRoot}guide/topics/graphics/view-animation.html#tween-animation">tween
+애니메이션</a>을 정의하는 XML 파일입니다 (속성 애니메이션도 이 디렉터리에 저장할 수 있지만
+두 가지 유형을 구분하기 위해 속성 애니메이션에는 {@code animator/} 디렉터리가 기본 설정됩니다
+).</td>
+ </tr>
+
+ <tr>
+ <td><code>color/</code></td>
+ <td>색상의 상태 목록을 정의하는 XML 파일입니다. <a href="color-list-resource.html">색상 상태
+목록 리소스</a>를 참조하십시오.</td>
+ </tr>
+
+ <tr>
+ <td><code>drawable/</code></td>
+
+ <td><p>다음 드로어블 리소스 하위 유형으로 컴파일 되는 비트맵 파일({@code .png}, {@code .9.png}, {@code .jpg}, {@code .gif}) 또는 XML 파일입니다.
+</p>
+ <ul>
+ <li>비트맵 파일</li>
+ <li>나인 패치(크기 조절 가능한 비트맵)</li>
+ <li>상태 목록</li>
+ <li>형태</li>
+ <li>드로어블 애니메이션</li>
+ <li>기타 드로어블</li>
+ </ul>
+ <p><a href="drawable-resource.html">드로어블 리소스</a>를 참조하십시오.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>mipmap/</code></td>
+ <td>각기 다른 시작 관리자 아이콘 밀도에 대한 드로어블 파일입니다.
+{@code mipmap/} 폴더로 시작 관리자 아이콘을 관리하는 자세한 방법은
+<a href="{@docRoot}tools/project/index.html#mipmap">프로젝트 관리 개요</a>를 참조하십시오.</td>
+ </tr>
+
+ <tr>
+ <td><code>layout/</code></td>
+ <td>사용자 인터페이스 레이아웃을 정의하는 XML 파일입니다.
+ <a href="layout-resource.html">레이아웃 리소스</a>를 참조하십시오.</td>
+ </tr>
+
+ <tr>
+ <td><code>menu/</code></td>
+ <td>옵션 메뉴, 컨텍스트 메뉴 또는 하위
+메뉴 등과 같은 애플리케이션 메뉴를 정의하는 XML입니다. <a href="menu-resource.html">메뉴 리소스</a>를 참조하십시오.</td>
+ </tr>
+
+ <tr>
+ <td><code>raw/</code></td>
+ <td><p>원시 형태로 저장하기 위한 임의의 파일입니다. 원시
+{@link java.io.InputStream}으로 이런 리소스를 열려면 리소스 ID, {@code R.raw.<em>filename</em>}으로 {@link android.content.res.Resources#openRawResource(int)
+Resources.openRawResource()}를 호출합니다.</p>
+ <p>그러나 원본 파일 이름과 파일 계층에 액세스해야 하는 경우,
+({@code res/raw/}가 아니라) {@code
+assets/} 디렉터리에 몇몇 리소스를 저장해두는 것을 고려해 볼 수 있습니다. {@code assets/}에 있는 파일에는
+리소스 ID가 주어지지 않으므로, 이들을 읽는 유일한 방법은 {@link android.content.res.AssetManager}를 사용하는 것뿐입니다.</p></td>
+ </tr>
+
+ <tr>
+ <td><code>values/</code></td>
+ <td><p>문자열, 정수 및 색과 같은 단순 값이 들어있는 XML 파일입니다.</p>
+ <p>다른 {@code res/} 하위 디렉터리에 있는 XML 리소스 파일은 XML 파일 이름을 근거로
+하나의 리소스를 정의하는 반면, {@code values/} 디렉터리에 있는 파일은 여러 개의 리소스를 설명합니다.
+이 디렉터리 안에 있는 파일의 경우, {@code &lt;resources&gt;} 요소의 각 하위 요소가 리소스를 하나씩
+정의합니다. 예를 들어 {@code &lt;string&gt;} 요소는
+{@code R.string} 리소스를 생성하고 {@code &lt;color&gt;} 요소는 {@code R.color}
+ 리소스를 생성합니다.</p>
+ <p>각 리소스가 자체 XML 요소로 정의되므로, 원하는 대로 파일을 정의하고 하나의 파일에 여러 가지 리소스 유형을
+배정할 수 있습니다. 하지만 명확히 하려면 여러 가지 파일에
+각기 고유한 리소스를 배치하는 것이 좋을 수도 있습니다. 예를 들어, 다음은 이 디렉터리에서 생성할 수 있는 리소스를 위한
+파일 이름 명명법입니다.</p>
+ <ul>
+ <li>리소스 배열을 위한 arrays.xml(<a href="more-resources.html#TypedArray">입력 배열</a>).</li>
+ <li><a href="more-resources.html#Color">색상 값</a>을 위한 colors.xml</li>
+ <li><a href="more-resources.html#Dimension">치수 값</a>을 위한 dimens.xml</li>
+ <li><a href="string-resource.html">문자열
+값</a>을 위한 strings.xml</li>
+ <li><a href="style-resource.html">스타일</a>을 위한 styles.xml</li>
+ </ul>
+ <p><a href="string-resource.html">문자열 리소스</a>,
+<a href="style-resource.html">스타일 리소스</a> 및
+<a href="more-resources.html">자세한 리소스 유형</a>을 참조하십시오.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>xml/</code></td>
+ <td>런타임에 읽을 수 있는 임의의 XML 파일로, 이때 {@link
+android.content.res.Resources#getXml(int) Resources.getXML()}을 호출하는 방법을 씁니다. 다양한 XML 구성 파일을 여기에 저장해야 합니다. 예를 들어
+<a href="{@docRoot}guide/topics/search/searchable-config.html">검색 가능한 구성</a> 등이 이에 해당됩니다.
+<!-- or preferences configuration. --></td>
+ </tr>
+</table>
+
+<p class="caution"><strong>주의:</strong> 리소스 파일을
+{@code res/} 디렉터리에 직접 저장하면 절대로 안 됩니다. 컴파일러 오류를 초래하게 됩니다.</p>
+
+<p>특정 유형의 리소스에 관한 자세한 정보는 <a href="available-resources.html">리소스 유형</a> 문서를 참조하십시오.</p>
+
+<p>표1에 정의된 하위 디렉터리에 저장하는 리소스는 "기본"
+리소스입니다. 다시 말해, 이러한 리소스가 애플리케이션의 기본 디자인과 콘텐츠를 정의한다는 뜻입니다.
+그러나, 여러 가지 유형의 Android 구동 기기는 각기 다른 유형의 리소스를 호출할 수도 있습니다.
+예를 들어 어느 기기의 화면이 보통보다 큰 편이라면, 추가적인 화면 공간의 이점을 활용할 수 있는
+다른 레이아웃 리소스를 제공해야 합니다. 또는, 기기에 다른 언어 설정이 있을 경우
+해당 텍스트를 사용자 인터페이스에 번역하는 다른 문자열 리소스를
+제공해야 합니다. 여러 가지 기기 구성에 여러 가지 리소스를 제공하려면,
+기본 리소스 외에 대체 리소스를
+제공해야 합니다.</p>
+
+
+<h2 id="AlternativeResources">대체 리소스 제공</h2>
+
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" />
+<p class="img-caption">
+<strong>그림 1.</strong> 서로 다른 두 개의 기기로, 서로 다른 레이아웃 리소스를 사용합니다.</p>
+</div>
+
+<p>거의 모든 애플리케이션이 특정 기기 구성을 지원하는
+대체 리소스를 제공해야 합니다. 예를 들어 여러 가지 화면 밀도에 맞는 대체 드로어블 리소스를
+포함시켜야 하며 여러 가지 언어에 맞게 대체 문자열 리소스도 포함시켜야 합니다. Android는 런타임에
+현재 기기 구성을 감지하고 애플리케이션에 대해 적절한 리소스를
+로드합니다.</p>
+
+<p>리소스 세트에 대하여 구성별로 적절한 대체를 지정하려면 다음과 같이 합니다.</p>
+<ol>
+ <li>{@code res/}에 {@code
+<em>&lt;resources_name&gt;</em>-<em>&lt;config_qualifier&gt;</em>} 형식으로 이름을 지정한 새 디렉터리를 만듭니다.
+ <ul>
+ <li><em>{@code &lt;resources_name&gt;}</em>은 해당 기본 리소스의 디렉터리 이름입니다(표1에 정의).
+</li>
+ <li><em>{@code &lt;qualifier&gt;}</em>는 리소스를 사용할 개별 구성을 지정하는
+이름입니다(표2에 정의).</li>
+ </ul>
+ <p>하나 이상의 <em>{@code &lt;qualifier&gt;}</em>를 추가할 수 있습니다. 각기 대시로
+구분합니다.</p>
+ <p class="caution"><strong>주의:</strong> 여러 한정자를 추가할 때는
+표2에 나열된 것과 같은 순서로 배치해야 합니다. 한정자의 순서가 잘못 지정되면
+해당 리소스가 무시됩니다.</p>
+ </li>
+ <li>해당되는 각 대체 리소스를 이 새 디렉터리에 저장하십시오. 이 리소스 파일은 기본 리소스 파일과
+똑같은 이름을 지정해야 합니다.</li>
+</ol>
+
+<p>예를 들어 다음은 기본 리소스와 대체 리소스입니다.</p>
+
+<pre class="classic no-pretty-print">
+res/
+ drawable/ <span style="color:black">
+ icon.png
+ background.png </span>
+ drawable-hdpi/ <span style="color:black">
+ icon.png
+ background.png </span>
+</pre>
+
+<p>{@code hdpi} 한정자는 해당 디렉터리의 리소스가
+고화질 화면 기기용이라는 것을 나타냅니다. 각 드로어블 디렉터리의 이미지는 특정 화면 화질에 맞추어
+크기가 지정되었으나 파일 이름은
+똑같습니다. 이렇게 하면 {@code icon.png} 또는 {@code
+background.png} 이미지를 참조하는 데 사용하는 리소스 ID는 항상 같지만 Android가 각 리소스 중에서 현재 기기에 가장 잘 일치하는
+버전을 선택하게 됩니다. 이때 리소스 디렉터리 이름의 한정자를 기기 구성 정보와
+비교하는 방법을 씁니다.</p>
+
+<p>Android는 여러 가지 구성 한정자를 지원하며 한 디렉터리 이름에
+여러 개의 한정자를 추가할 수 있습니다. 각 한정자를 대시로 구분하면 됩니다. 표 2는
+유효한 구성 한정자를 우선 순위대로 나열한 것입니다. 리소스 디렉터리에 여러 개의
+한정자를 사용하는 경우, 해당 한정자를 디렉터리 이름에 추가할 때 이 표에 나열된 것과 같은
+순서로 추가해야 합니다.</p>
+
+
+<p class="table-caption" id="table2"><strong>표 2.</strong> 구성 한정자
+이름입니다.</p>
+<table>
+ <tr>
+ <th>구성</th>
+ <th>한정자 값</th>
+ <th>설명</th>
+ </tr>
+ <tr id="MccQualifier">
+ <td>MCC 및 MNC</td>
+ <td>예:<br/>
+ <code>mcc310</code><br/>
+ <code><nobr>mcc310-mnc004</nobr></code><br/>
+ <code>mcc208-mnc00</code><br/>
+ 등.
+ </td>
+ <td>
+ <p>이동통신 국가 코드(MCC)에 선택적으로 이동통신 네트워크 코드(MNC)가 이어지는 형태로,
+기기의 SIM 카드에서 가져옵니다. 예를 들어, <code>mcc310</code>은 모든 이동통신사를 포함한 미국이고,
+<code>mcc310-mnc004</code>는 Verizon을 사용하는 미국, <code>mcc208-mnc00</code>은 Orange를 사용하는
+프랑스입니다.</p>
+ <p>기기가 무선 연결(GSM 전화)을 사용할 경우, MCC와 MNC 값은
+SIM 카드에서 가져옵니다.</p>
+ <p>MCC만 단독으로 사용할 수도 있습니다(예를 들어, 애플리케이션에 국가별 합법적 리소스를
+ 포함하는 경우). 언어에 기초해서만 지정해야 할 경우,
+<em>언어 및 지역</em> 한정자를 대신 사용합니다(아래에 설명). MCC와
+MNC 한정자를 사용할 경우, 조심해서 사용하고 예상한 대로 작동하는지 테스트해야 합니다.</p>
+ <p>또한, 구성 필드 {@link
+android.content.res.Configuration#mcc}와 {@link
+android.content.res.Configuration#mnc}를 참조하십시오. 이 구성 필드는 각각 이동통신 국가 코드와
+이동통신 네트워크 코드를 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="LocaleQualifier">
+ <td>언어 및 지역</td>
+ <td>예:<br/>
+ <code>en</code><br/>
+ <code>fr</code><br/>
+ <code>en-rUS</code><br/>
+ <code>fr-rFR</code><br/>
+ <code>fr-rCA</code><br/>
+ 등.
+ </td>
+ <td><p>언어는 두 글자의 <a href="http://www.loc.gov/standards/iso639-2/php/code_list.php">ISO
+639-1</a> 언어 코드로 정의되고,
+뒤이어 두 글자의 <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO
+3166-1-alpha-2</a> 지역 코드가 선택적으로 따라옵니다(소문자 "{@code r}" 뒤에 붙음).
+ </p><p>
+ 코드는 대소문자를 구별하지 <em>않습니다</em>. {@code r} 접두사는
+지역 부분을 구별하기 위해 사용합니다.
+ 지역만 지정할 수는 없습니다.</p>
+ <p>사용자가 시스템 설정에서 언어를 변경할 경우
+애플리케이션 수명 중에 변경될 수 있습니다. 런타임에서 애플리케이션에 어떤 영향을 미치는지 자세히 알아보려면 <a href="runtime-changes.html">런타임 변경 처리</a>를 참조하십시오.
+</p>
+ <p>다른 여러 언어에 맞게 애플리케이션을 지역화하기 위한 전체 지침은
+<a href="localization.html">지역화</a>를 참조하십시오.</p>
+ <p>또한, 현재 로케일을 나타내는 {@link android.content.res.Configuration#locale} 구성 필드도
+참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="LayoutDirectionQualifier">
+ <td>레이아웃 방향</td>
+ <td><code>ldrtl</code><br/>
+ <code>ldltr</code><br/>
+ </td>
+ <td><p>애플리케이션의 레이아웃 방향입니다. {@code ldrtl}는 "오른쪽에서 왼쪽 방향 레이아웃"을 나타냅니다.
+{@code ldltr}는 "왼쪽에서 오른쪽 방향 레이아웃"을 나타내고 기본 암시적 값입니다.
+ </p>
+ <p>이는 레이아웃이나 드로어블, 값 등의 모든 리소스에 적용할 수 있습니다.
+ </p>
+ <p>예를 들어, 아랍어에 대한 특정 레이아웃을 제공하고
+다른 "오른쪽에서 왼쪽으로 쓰는" 언어(히브리어 또는 페르시아어)에 제네릭 레이아웃을 제공하고 싶다면 다음과 같이 해야 합니다.
+ </p>
+<pre class="classic no-pretty-print">
+res/
+ layout/ <span style="color:black">
+ main.xml </span>(Default layout)
+ layout-ar/ <span style="color:black">
+ main.xml </span>(Specific layout for Arabic)
+ layout-ldrtl/ <span style="color:black">
+ main.xml </span>(Any "right-to-left" language, except
+ for Arabic, because the "ar" language qualifier
+ has a higher precedence.)
+</pre>
+ <p class="note"><strong>참고:</strong> 앱에서 오른쪽에서 왼쪽 레이아웃 기능을 활성화하려면
+<a href="{@docRoot}guide/topics/manifest/application-element.html#supportsrtl">{@code
+supportsRtl}</a>을 {@code "true"}로 설정하고 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>을 17 이상으로 설정해야 합니다.</p>
+ <p><em>API 레벨 17에서 추가되었습니다.</em></p>
+ </td>
+ </tr>
+ <tr id="SmallestScreenWidthQualifier">
+ <td>smallestWidth</td>
+ <td><code>sw&lt;N&gt;dp</code><br/><br/>
+ 예:<br/>
+ <code>sw320dp</code><br/>
+ <code>sw600dp</code><br/>
+ <code>sw720dp</code><br/>
+ 등.
+ </td>
+ <td>
+ <p>화면의 기본 크기로, 사용 가능한 화면 영역의 가장 짧은 치수가
+나타냅니다. 구체적으로 기기의 smallestWidth는 해당 화면의 이용 가능한 높이와 너비의
+가장 짧은 치수를 말합니다(이것을 화면에 대한 "가능한 한 가장 좁은 너비"로 생각해도 됩니다). 이 한정자를 사용하면
+화면의 현재 방향에 관계 없이
+애플리케이션이 해당 UI에서 이용 가능한 너비 중 최소 {@code &lt;N&gt;}dps를 확보하도록 할 수 있습니다.</p>
+ <p>예를 들어, 레이아웃에 언제나
+600dp 이상의 화면 최소 치수가 필요하다면, 이 한정자를 사용하여 레이아웃 리소스, {@code
+res/layout-sw600dp/}를 만들 수 있습니다. 시스템이 이러한 리소스를 사용하는 것은 사용 가능한 화면의 최소 치수가 적어도 600dp가
+되는 경우뿐이며, 이때 600dp라는 크기가 사용자 쪽에서 보기에 높이이든 너비이든
+관계 없습니다. 이 smallestWidth는 기기의 고정된 화면 크기 특성입니다. <strong>
+기기의 smallestWidth는 화면 방향이 변경되어도 바뀌지 않습니다</strong>.</p>
+ <p>기기의 smallestWidth는 화면 장식과 시스템 UI를 감안합니다. 예를 들어,
+화면 상에서 최소 너비의 축 주변 공간을 차지하는 영구 UI 요소가 있다면,
+시스템은 smallestWidth를 실제 화면 크기보다 작게 선언합니다.
+이것은 개발자의 UI가 사용할 수 없는 화면 픽셀이기 때문입니다. 따라서 개발자가 사용하는 값은
+<em>레이아웃에서 요구하는</em> 실제 최소 치수여야 합니다(일반적으로 이 값은 화면의 현재 방향과 관계없이
+레이아웃이 지원하는 "최소 너비"가 됩니다.).</p>
+ <p>다음의 몇몇 값은 보편적인 화면 크기에 대하여 사용할 수 있습니다.</p>
+ <ul>
+ <li>화면 크기 320에 화면 구성이 아래와 같은 기기:
+ <ul>
+ <li>240x320ldpi(QVGA 핸드셋)</li>
+ <li>320x480mdpi(핸드셋)</li>
+ <li>480x800hdpi(고화질 핸드셋)</li>
+ </ul>
+ </li>
+ <li>480x800mdpi(태블릿/핸드셋) 등의 화면에는 480을 사용합니다.</li>
+ <li>600x1024mdpi (7인치 태블릿) 등의 화면에는 600을 사용합니다.</li>
+ <li>720x1280mdpi (10인치 태블릿) 등의 화면에는 720을 사용합니다.</li>
+ </ul>
+ <p>애플리케이션이
+smallestWidth 한정자의 여러 값이 포함된 여러 리소스 디렉터리를 제공하면, 시스템은
+기기의 smallestWidth에 가장 가까운(그러나 이를 초과하지 않는) 값을 사용합니다. </p>
+ <p><em>API 레벨 13에서 추가되었습니다.</em></p>
+ <p>이외에도 애플리케이션과 호환되는 최소한의 smallestWidth를 선언하는 <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html#requiresSmallest">{@code
+android:requiresSmallestWidthDp}</a> 속성과
+기기의 smallestWidth 값을 보유한 {@link
+android.content.res.Configuration#smallestScreenWidthDp}
+구성 필드도 참조하십시오.</p>
+ <p>여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는
+<a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a> 개발자 가이드를 참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="ScreenWidthQualifier">
+ <td>이용 가능한 너비</td>
+ <td><code>w&lt;N&gt;dp</code><br/><br/>
+ 예:<br/>
+ <code>w720dp</code><br/>
+ <code>w1024dp</code><br/>
+ 등.
+ </td>
+ <td>
+ <p>리소스를 사용해야 하는 {@code dp} 단위에서 최소 이용 가능한 화면 너비를 지정합니다.
+이는 <code>&lt;N&gt;</code> 값이 정의합니다. 이 구성
+값은 현재 실제 너비에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때
+변경됩니다.</p>
+ <p>애플리케이션이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉터리를 제공하면,
+시스템은 기기의 현재 화면 너비에 가장 가까운(그러나 이를 초과하지 않는)
+값을 사용합니다. 이 값은
+화면 장식을 감안한 것이므로, 기기의 왼쪽이나 오른쪽 가장자리에
+영구 UI 요소가 있을 경우, 기기는
+이러한 UI 요소를 감안하여 애플리케이션의 이용 가능한 공간을 줄여서
+ 실제 화면 크기보다 작은 너비 값을 사용합니다.</p>
+ <p><em>API 레벨 13에서 추가되었습니다.</em></p>
+ <p>현재 화면 너비를 보유한 {@link android.content.res.Configuration#screenWidthDp}
+ 구성 필드도 참조하십시오.</p>
+ <p>여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는
+<a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a> 개발자 가이드를 참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="ScreenHeightQualifier">
+ <td>이용 가능한 높이</td>
+ <td><code>h&lt;N&gt;dp</code><br/><br/>
+ 예:<br/>
+ <code>h720dp</code><br/>
+ <code>h1024dp</code><br/>
+ 등.
+ </td>
+ <td>
+ <p>리소스가 사용되어야 하는 최소한의 사용 가능한 화면 높이를 "dp" 단위로 나타냅니다.
+이는 <code>&lt;N&gt;</code> 값이 정의합니다. 이 구성
+값은 현재 실제 높이에 맞추기 위해 화면 방향이 가로와 세로 사이를 오가며 바뀔 때
+변경됩니다.</p>
+ <p>애플리케이션이 이 구성에 대해 서로 다른 값이 포함된 여러 개의 리소스 디렉터리를 제공하면,
+시스템은 기기의 현재 화면 높이에 가장 가까운(그러나 이를 초과하지 않는)
+값을 사용합니다. 이 값은
+화면 장식을 감안한 것이므로, 기기의 상단이나 하단 가장자리에
+영구 UI 요소가 있을 경우, 기기는
+이러한 UI 요소를 감안하여 애플리케이션의 이용 가능한 공간을 줄여서
+ 실제 화면 크기보다 작은 높이 값을 사용합니다.
+상태 표시줄에 고정되지 않은 화면 장식(예를 들어
+전화 상태 표시줄은 전체 화면에서 숨길 수 있음)은 여기에서 감안하지 <em>않았고</em>,
+제목 표시줄이나 작업 모음 등의 창 장식도 감안되지 않았으므로, 애플리케이션 입장에서는 자신이 지정한 것보다 어느 정도 작은 공간을
+받아들일 대비를 해야 합니다.
+ <p><em>API 레벨 13에서 추가되었습니다.</em></p>
+ <p>현재 화면 너비를 보유한 {@link android.content.res.Configuration#screenHeightDp}
+ 구성 필드도 참조하십시오.</p>
+ <p>여러 가지 화면에 맞는 디자인과 한정자 사용에 관한 자세한 정보는
+<a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a> 개발자 가이드를 참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="ScreenSizeQualifier">
+ <td>화면 크기</td>
+ <td>
+ <code>small</code><br/>
+ <code>normal</code><br/>
+ <code>large</code><br/>
+ <code>xlarge</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code small}: 저밀도 QVGA 화면과 비슷한
+크기의 화면입니다. 작은 화면의 최소 레이아웃 크기는
+약 320x426 dp단위입니다. 이 화면의 예시로는 QVGA 저밀도 및 VGA 고밀도가
+있습니다.</li>
+ <li>{@code normal}: 중밀도 HVGA 화면과
+비슷한 크기의 화면입니다. 정상 화면의
+ 최소 레이아웃 크기는 약 320x470 dp 단위입니다. 이 화면의 예로는
+WQVGA 저밀도, HVGA 중밀도, WVGA 고밀도 등이 있습니다.
+</li>
+ <li>{@code large}: 중밀도 VGA 화면과
+비슷한 크기의 화면입니다.
+ 큰 화면의 최소 레이아웃 크기는 약 480x640 dp 단위입니다.
+ 이 화면의 예시로는 VGA 및 WVGA 중밀도 화면이 있습니다.</li>
+ <li>{@code xlarge}: 일반적인 중밀도 HVGA 화면보다 상당히 큰 화면을
+말합니다. 초대형 화면의
+ 최소 레이아웃 크기는 약 720x960 dp 단위입니다. 대부분의 경우, 초대형 화면 기기는
+주머니에 넣어 다니기에 너무 큽니다. 따라서 태블릿 스타일의 기기일 가능성이
+높습니다. <em>API 레벨 9에서 추가되었습니다.</em></li>
+ </ul>
+ <p class="note"><strong>참고:</strong> 크기 한정자를 사용하더라도 해당 리소스가 그 크기의 화면
+<em>전용</em>이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를
+제공하지 않으면,
+시스템이 <a href="#BestMatch">가장 잘 일치하는</a> 리소스를 사용합니다.</p>
+ <p class="caution"><strong>주의:</strong> 모든 리소스가 현재 화면보다
+<em>큰</em> 크기 한정자를 사용하는 경우, 시스템은 리소스를 사용하지 <strong>않으며</strong> 애플리케이션은 런타임에 작동이 중단됩니다(예를 들어, 모든 레이아웃 리소스에 {@code
+xlarge} 한정자가 태그되어 있지만 기기는 일반 크기 화면일 경우
+).</p>
+ <p><em>API 레벨 4에서 추가되었습니다.</em></p>
+
+ <p>자세한 정보는 <a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a>을 참조하십시오.</p>
+ <p>{@link android.content.res.Configuration#screenLayout} 구성 필드도 참조하십시오.
+이것은 화면이 소형, 일반 크기 또는
+대형인지를 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="ScreenAspectQualifier">
+ <td>화면 비율</td>
+ <td>
+ <code>long</code><br/>
+ <code>notlong</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code long}: WQVGA, WVGA, FWVGA 등의 긴 화면</li>
+ <li>{@code notlong}: QVGA, HVGA 및 VGA 등의 길지 않은 화면</li>
+ </ul>
+ <p><em>API 레벨 4에서 추가되었습니다.</em></p>
+ <p>이것은 순전히 화면 비율에만 기초합니다("긴" 화면이 더 넓습니다). 이는
+화면 방향과 관계가 없습니다.</p>
+ <p>{@link android.content.res.Configuration#screenLayout}도 참조하십시오.
+이것은 화면이 긴 화면인지 여부를 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="OrientationQualifier">
+ <td>화면 방향</td>
+ <td>
+ <code>port</code><br/>
+ <code>land</code> <!-- <br/>
+ <code>square</code> -->
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code port}: 기기가 세로 방향(수직)입니다.</li>
+ <li>{@code land}: 기기가 가로 방향(수평)입니다.</li>
+ <!-- Square mode is currently not used. -->
+ </ul>
+ <p>이것은 사용자가 화면을 돌리는 경우 애플리케이션 수명 중에
+변경될 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면
+<a href="runtime-changes.html">런타임 변경 처리</a>를 참조하십시오.</p>
+ <p>{@link android.content.res.Configuration#orientation} 구성 필드도 참조하십시오.
+이는 현재 기기 방향을 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="UiModeQualifier">
+ <td>UI 모드</td>
+ <td>
+ <code>car</code><br/>
+ <code>desk</code><br/>
+ <code>television</code><br/>
+ <code>appliance</code>
+ <code>watch</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code car}: 기기가 차량용 도크에서 표시되고 있습니다.</li>
+ <li>{@code desk}: 기기가 데스크용 도크에서 표시되고 있습니다.</li>
+ <li>{@code television}: 기기가 텔레비전에서 표시되고 있으며,
+UI가 큰 화면에 있고 사용자가 여기에서 멀리 떨어져 있는
+"텐 풋(ten foot)" 환경을 제공하고 있습니다. 이는 주로 DPAD 또는
+기타 비-포인터 상호 작용 주변을 가리킵니다.</li>
+ <li>{@code appliance}: 기기가 가전 제품 역할을 하고 있으며, 디스플레이
+화면이 없습니다.</li>
+ <li>{@code watch}: 기기에 디스플레이 화면이 있고 손목에 착용됩니다.</li>
+ </ul>
+ <p><em>API 레벨 8에서 추가되었고, 텔레비전은 API 13에서, 시계는 API 20에서 추가되었습니다.</em></p>
+ <p>기기가 도크에 삽입되거나 제거될 때 앱이 응답하는 방식에 관한 정보는
+<a href="{@docRoot}training/monitoring-device-state/docking-monitoring.html">도킹 상태 및 유형
+판별과 모니터링</a>을 읽어보십시오.</p>
+ <p>이것은 사용자가 기기를 도크에 놓는 경우 애플리케이션 수명 중에
+변경될 수 있습니다. 이러한 모드 중 몇 가지는 {@link
+android.app.UiModeManager}를 사용하여 활성화 또는 비활성화할 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 <a href="runtime-changes.html">런타임 변경 처리</a>를
+참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="NightQualifier">
+ <td>야간 모드</td>
+ <td>
+ <code>night</code><br/>
+ <code>notnight</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code night}: 야간</li>
+ <li>{@code notnight}: 주간</li>
+ </ul>
+ <p><em>API 레벨 8에서 추가되었습니다.</em></p>
+ <p>이것은 야간 모드가 자동 모드인 상태(기본)에서 애플리케이션의 수명 중에
+변경될 수 있습니다. 이 경우 모드는 하루 중 시간대를 기반으로 변경됩니다. 이 모드는
+{@link android.app.UiModeManager}를 사용하여 활성화 또는 비활성화할 수 있습니다. 이것이 런타임 중 애플리케이션에 어떤 영향을 미치는지 알아보려면 <a href="runtime-changes.html">런타임 변경 처리</a>를
+참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="DensityQualifier">
+ <td>화면 픽셀 밀도(dpi)</td>
+ <td>
+ <code>ldpi</code><br/>
+ <code>mdpi</code><br/>
+ <code>hdpi</code><br/>
+ <code>xhdpi</code><br/>
+ <code>xxhdpi</code><br/>
+ <code>xxxhdpi</code><br/>
+ <code>nodpi</code><br/>
+ <code>tvdpi</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code ldpi}: 저밀도 화면, 약 120dpi.</li>
+ <li>{@code mdpi}: 중밀도(일반적인 HVGA에서) 화면, 약
+160dpi.</li>
+ <li>{@code hdpi}: 고밀도 화면, 약 240dpi.</li>
+ <li>{@code xhdpi}: 초고밀도 화면, 약 320dpi. <em>API 레벨 8에서
+추가되었습니다.</em></li>
+ <li>{@code xxhdpi}: 슈퍼 초고밀도 화면, 약 480dpi. <em>API 레벨 16에서
+추가되었습니다.</em></li>
+ <li>{@code xxxhdpi}: 울트라 슈퍼 초고밀도 화면 사용(시작 관리자 아이콘만 해당,
+<em>다중 화면 지원</em>의
+<a href="{@docRoot}guide/practices/screens_support.html#xxxhdpi-note">참고</a>를 참조하십시오), 약 640dpi. <em>API 레벨 18에서
+추가되었습니다.</em></li>
+ <li>{@code nodpi}: 이것은 기기 밀도에 일치하도록 크기를 조정하고자 하지 않는 비트맵 리소스에
+사용할 수 있습니다.</li>
+ <li>{@code tvdpi}: Mdpi와 hdpi 사이 어딘가에 해당되는 화면, 약 213dpi. 이것은
+"기본" 밀도 그룹으로 간주되지 않습니다. 이는 대체로 텔레비전용으로 만들어진 것이며
+대부분의 앱에는 필요하지 않는 것이 정상입니다. mdpi 및 hdpi만 제공하면 대부분의 앱에는 충분하고
+시스템이 필요에 따라 크기를 조정해줍니다. 이 한정자는 API 레벨 13과 함께 도입되었습니다.</li>
+ </ul>
+ <p>여섯 가지 기본 밀도간에 3:4:6:8:12:16 비율 척도가 있습니다(tvdpi 밀도는
+무시). 그러므로 ldpi의 9x9 비트맵은 mdpi에서 12x12이고, hdpi에서 18x18, xhdpi에서 24x24 등, 이런 식으로 적용됩니다.
+</p>
+ <p>이미지 리소스가 텔레비전이나 특정 기기에서 제대로 보이지 않는다고 결정하고
+tvdpi 리소스를 사용하려 할 경우, 배율은 1.33*mdpi입니다. 예를 들어,
+mdpi 화면의 100px x 100px 이미지는 tvdpi에서 133px x 133px가 되어야 합니다.</p>
+ <p class="note"><strong>참고:</strong> 밀도 한정자를 사용하더라도 해당 리소스가 그 밀도의 화면
+<em>전용</em>이라는 뜻은 아닙니다. 현재 기기 구성과 더욱 잘 맞는 한정자가 포함된 대체 리소스를
+제공하지 않으면,
+시스템이 <a href="#BestMatch">가장 잘 일치하는</a> 리소스를 사용합니다.</p>
+ <p>다양한 화질을 처리하는 방법과
+Android가 현재 화질에 맞춰 비트맵을 축소하는 방법에 관한 자세한 정보는 <a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a>을 참조하십시오.</p>
+ </td>
+ </tr>
+ <tr id="TouchscreenQualifier">
+ <td>터치 스크린 유형</td>
+ <td>
+ <code>notouch</code><br/>
+ <code>finger</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code notouch}: 기기에 터치 스크린이 없습니다.</li>
+ <li>{@code finger}: 기기에 터치 스크린이 있으며 이를
+사용자의 손가락을 사용한 방향 지시 상호 작용을 통해 쓰도록 되어 있습니다.</li>
+ </ul>
+ <p>{@link android.content.res.Configuration#touchscreen} 구성 필드도 참조하십시오.
+이는 기기에서 사용되는 터치 스크린의 유형을 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="KeyboardAvailQualifier">
+ <td>키보드 가용성</td>
+ <td>
+ <code>keysexposed</code><br/>
+ <code>keyshidden</code><br/>
+ <code>keyssoft</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code keysexposed}: 기기에서 키보드를 사용할 수 있습니다. 키보드에
+소프트웨어 키보드가 활성화되어 있으면(이럴 가능성이 큽니다), 하드웨어 키보드가 사용자에게 노출되어 있지
+<em>않거나</em> 기기에 하드웨어 키보드가 없더라도 이 리소스를 사용할 수 있습니다. 소프트웨어
+키보드가 제공되어 있지 않거나 비활성화되어 있는 경우 이것은 하드웨어 키보드가 노출되어 있을 때에만
+사용할 수 있습니다.</li>
+ <li>{@code keyshidden}: 기기에서 하드웨어 키보드를 사용할 수 있지만
+숨겨져 있고 <em>이에 더하여</em> 기기에 소프트웨어 키보드가 활성화되어 있지 <em>않습니다</em>.</li>
+ <li>{@code keyssoft}: 기기에 활성화된 소프트웨어 키보드가 있습니다(표시 여부는
+무관).</li>
+ </ul>
+ <p><code>keysexposed</code> 리소스를 제공하지만 <code>keyssoft</code>
+리소스는 제공하지 않는다면, 시스템은 소프트웨어 키보드가 활성화되어 있는 동안은 키보드가 보이는지 여부와 관계없이 <code>keysexposed</code>
+리소스를 사용합니다.</p>
+ <p>이것은 사용자가 하드웨어 키보드를 여는 경우 애플리케이션 수명 중에
+변경될 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 <a href="runtime-changes.html">런타임 변경 처리</a>를
+참조하십시오.</p>
+ <p>또한, 구성 필드 {@link
+android.content.res.Configuration#hardKeyboardHidden}과 {@link
+android.content.res.Configuration#keyboardHidden}을 참조하십시오. 이 필드는 각각 하드웨어 키보드의 가시성과
+모든 종류의 키보드(소프트웨어 포함)의 가시성을 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="ImeQualifier">
+ <td>기본 텍스트 입력 메서드</td>
+ <td>
+ <code>nokeys</code><br/>
+ <code>qwerty</code><br/>
+ <code>12key</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code nokeys}: 기기에 텍스트 입력을 위한 하드웨어 키가 없습니다.</li>
+ <li>{@code qwerty}: 기기에 하드웨어 쿼티 키보드가 있습니다(이것이
+사용자
+에게 표시되는지 여부는 무관).</li>
+ <li>{@code 12key}: 기기에 하드웨어 12-키 키보드가 있습니다(이것이 사용자에게 표시되는지 여부는
+무관).</li>
+ </ul>
+ <p>{@link android.content.res.Configuration#keyboard} 구성 필드도 참조하십시오.
+이는 기본 텍스트 입력 메서드를 사용할 수 있는지 여부를 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="NavAvailQualifier">
+ <td>탐색 키 가용성</td>
+ <td>
+ <code>navexposed</code><br/>
+ <code>navhidden</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code navexposed}: 사용자가 탐색 키를 사용할 수 있습니다.</li>
+ <li>{@code navhidden}: 탐색 키를 사용할 수 없습니다(예: 닫힌 뚜껑 뒤에 있는
+경우).</li>
+ </ul>
+ <p>이것은 사용자가 탐색 키를 드러내는 경우 애플리케이션 수명 중에
+변경될 수 있습니다. 이것이 런타임에 애플리케이션에 어떤 영향을 미치는지 알아보려면 <a href="runtime-changes.html">런타임 변경 처리</a>를
+참조하십시오.</p>
+ <p>{@link android.content.res.Configuration#navigationHidden} 구성
+필드도 참조하십시오. 이는 탐색 키가 숨겨져 있는지 여부를 나타냅니다.</p>
+ </td>
+ </tr>
+ <tr id="NavigationQualifier">
+ <td>기본 비터치 탐색 메서드</td>
+ <td>
+ <code>nonav</code><br/>
+ <code>dpad</code><br/>
+ <code>trackball</code><br/>
+ <code>wheel</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code nonav}: 기기에 터치 스크린을 제외하고 다른 탐색 기능이
+없습니다.</li>
+ <li>{@code dpad}: 기기에 탐색용 방향 패드(d-pad)가 있습니다.</li>
+ <li>{@code trackball}: 기기에 탐색용 트랙볼이 있습니다.</li>
+ <li>{@code wheel}: 기기에 탐색용 방향 휠이 있습니다.</li>
+ </ul>
+ <p>{@link android.content.res.Configuration#navigation} 구성 필드도 참조하십시오.
+이는 사용 가능한 탐색 메서드의 유형을 나타냅니다.</p>
+ </td>
+ </tr>
+<!-- DEPRECATED
+ <tr>
+ <td>Screen dimensions</td>
+ <td>Examples:<br/>
+ <code>320x240</code><br/>
+ <code>640x480</code><br/>
+ etc.
+ </td>
+ <td>
+ <p>The larger dimension must be specified first. <strong>This configuration is deprecated
+and should not be used</strong>. Instead use "screen size," "wider/taller screens," and "screen
+orientation" described above.</p>
+ </td>
+ </tr>
+-->
+ <tr id="VersionQualifier">
+ <td>플랫폼 버전(API 레벨)</td>
+ <td>예:<br/>
+ <code>v3</code><br/>
+ <code>v4</code><br/>
+ <code>v7</code><br/>
+ 등.</td>
+ <td>
+ <p>기기에서 지원하는 API 레벨입니다. 예를 들어, <code>v1</code>는 API 레벨
+1용이고(Android 1.0 이상 기기), <code>v4</code>는 API 레벨 4용(Android
+1.6 이상 기기)입니다. 이러한 값에 관한 자세한 정보는 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Android API 레벨</a> 문서를
+참조하십시오.</p>
+ </td>
+ </tr>
+</table>
+
+
+<p class="note"><strong>참고:</strong> 일부 구성 한정자는 Android
+1.0 이후부터 추가되었으므로 모든 Android 버전이 모든 한정자를 지원하는 것은 아닙니다. 새로운 한정자를 사용하면 암시적으로
+플랫폼 버전 한정자도 추가하므로 구형 기기가 이를 무시하게 됩니다. 예를 들어
+<code>w600dp</code> 한정자를 사용하면 자동적으로 <code>v13</code> 한정자를 포함합니다.
+사용 가능한 너비 한정자가 API 레벨 13부터 새로 도입되었기 때문입니다. 문제를 애초에 피하려면, 항상
+기본 리소스를 한 세트 포함하세요(<em>한정자 없는</em> 리소스 한 세트). 자세한 정보는
+<a href="#Compatibility">리소스와 연관된 최선의 기기 호환성 제공
+</a>을 참조하십시오.</p>
+
+
+
+<h3 id="QualifierRules">한정자 이름 규칙</h3>
+
+<p>다음은 구성 한정자 이름 사용에 관한 규칙입니다.</p>
+
+<ul>
+ <li>한 가지 리소스 세트에 여러 개의 한정자를 사용할 수 있으며, 이를 대시로 구분하면 됩니다. 예를 들어,
+<code>drawable-en-rUS-land</code>는 수평 방향의
+US-English 기기에 적용합니다.</li>
+ <li>한정자는 <a href="#table2">표2</a>에 나열된 순서를 따라야 합니다. 예:
+
+ <ul>
+ <li>잘못된 배열: <code>drawable-hdpi-port/</code></li>
+ <li>맞는 배열: <code>drawable-port-hdpi/</code></li>
+ </ul>
+ </li>
+ <li>대체 리소스 디렉터리는 중첩될 수 없습니다. 예를 들어,
+<code>res/drawable/drawable-en/</code>는 있을 수 없습니다.</li>
+ <li>값은 대소문자를 구분하지 않습니다. 리소스 컴파일러가 처리 전에 디렉터리 이름을
+소문자로 바꿔 대소문자를 구분하지 않는
+파일 시스템에서 문제를 일으키지 않도록 방지합니다. 이름에 대문자가 있는 것은 오로지 가독성을 향상하기 위해서입니다.</li>
+ <li>각 한정자 유형마다 한 개의 값만 지원됩니다. 예를 들어, 스페인과 프랑스에
+같은 드로어블 파일을 사용하고자 하는 경우 디렉터리 이름이
+<code>drawable-rES-rFR/</code>이면 <em>안 됩니다.</em> 대신
+<code>drawable-rES/</code>와 <code>drawable-rFR/</code> 같이 적절한 파일이 포함된 두 개의 리소스 디렉터리가 필요합니다.
+그러나 두 위치에서 같은 파일을 실제로 복제할 필요는 없습니다. 대신
+리소스에 별명을 만들면 됩니다. 아래의 <a href="#AliasResources">별명 리소스
+생성</a>을 참조하십시오.</li>
+</ul>
+
+<p>이런 한정자로 이름을 지은 디렉터리에 대체 리소스를 저장하고 나면
+Android가 현재 기기 구성에 기초하여 애플리케이션에 자동으로 리소스를 적용합니다.
+ 리소스가 요청될 때마다 Android가 요청한 리소스 파일이 들어있는
+대체 리소스 디렉터리를 확인하고, 그런 다음 <a href="#BestMatch">가장 잘 일치하는
+리소스를 찾습니다</a>(아래에서 논함). 특정 기기 구성에 일치하는 대체 리소스가 없는 경우,
+Android는 상응하는 기본 리소스(구성 한정자를 포함하지 않는
+특정 리소스 유형에 대한 리소스 세트
+)를 사용합니다.</p>
+
+
+
+<h3 id="AliasResources">별명 리소스 생성</h3>
+
+<p>어떤 리소스를 하나 이상의 기기 구성에서 사용하고자 하는 경우(그렇지만
+이를 기본 리소스를 제공하는 것은 원치 않는 경우), 같은 리소스를 하나 이상의 대체 리소스 디렉터리에
+넣지 않아도 됩니다. 대신, 기본 리소스 디렉터리에 저장된 리소스에 대해 별명 역할을 하는
+대체
+리소스를 만들면 됩니다(경우에 따라).</p>
+
+<p class="note"><strong>참고:</strong> 모든 리소스가 다른 리소스에 대한
+별명을 생성할 수 있는 메커니즘을 제공하는 것은 아닙니다. 특히, {@code xml/} 디렉터리의 애니메이션, 메뉴, 원시 및 기타 지정되지 않은
+리소스는 이 기능을 제공하지 않습니다.</p>
+
+<p>예를 들어, 애플리케이션 아이콘 {@code icon.png}이 있고 서로 다른 로케일에서 이 아이콘의 고유 버전이
+필요한 경우가 있습니다. 그러나 두 로케일, English-Canadian과 French-Canadian은 같은 버전을
+사용해야 합니다. 같은 이미지를 English-Canadian과 French-Canadian 양쪽
+모두에 대한 리소스 디렉터리에 복사해야 한다고 생각할 수 있지만, 실은
+그렇지 않습니다. 대신, 두 로케일에서 사용하는 이미지를 {@code icon_ca.png}(
+{@code icon.png} 이외에 어떤 이름이든 가능)로 저장하고 이를
+기본 {@code res/drawable/} 디렉터리에 넣으면 됩니다. 그런 다음 {@code icon.xml} 파일을 {@code icon_ca.png}
+리소스를 참조하는 {@code
+res/drawable-en-rCA/} 및 {@code res/drawable-fr-rCA/}로 생성합니다. 이때, {@code &lt;bitmap&gt;} 요소를 사용하면 됩니다. 이렇게 하면
+PNG 파일 버전 하나와 그것을 가리키는 작은 XML 파일 두 개만 저장할 수 있습니다. (XML 파일 예시는 아래와 같습니다.)</p>
+
+
+<h4>드로어블</h4>
+
+<p>기존 드로어블에 별명을 생성하려면 {@code &lt;bitmap&gt;} 요소를 사용합니다.
+예를 들면 다음과 같습니다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/icon_ca" />
+</pre>
+
+<p>파일을 (
+{@code res/drawable-en-rCA/}와 같은 대체 리소스 디렉터리에) {@code icon.xml}로 저장하면,
+{@code R.drawable.icon}으로 참조할 수 있지만 실제로는 {@code
+R.drawable.icon_ca} 리소스({@code res/drawable/}에 저장됨)의 별명인 리소스로 컴파일링됩니다.</p>
+
+
+<h4>레이아웃</h4>
+
+<p>기존 레이아웃에 별명을 생성하려면 {@code &lt;merge&gt;}로 래핑되어 있는 {@code &lt;include&gt;}
+요소를 사용합니다. 예:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;merge>
+ &lt;include layout="@layout/main_ltr"/>
+&lt;/merge>
+</pre>
+
+<p>파일을 {@code main.xml}로 저장하면, {@code R.layout.main}으로 참조할 수 있지만 실제로는 {@code R.layout.main_ltr}
+ 리소스의 별명인 리소스로
+컴파일링됩니다.</p>
+
+
+<h4>문자열 및 기타 단순 값</h4>
+
+<p>기존 문자열에 별명을 생성하려면 원하는 문자열의 리소스 ID를
+새 문자열의 값으로 사용하면 됩니다. 예:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string name="hello">Hello&lt;/string>
+ &lt;string name="hi">@string/hello&lt;/string>
+&lt;/resources>
+</pre>
+
+<p>이제 {@code R.string.hi} 리소스는 {@code R.string.hello}의 별명입니다.</p>
+
+<p> <a href="{@docRoot}guide/topics/resources/more-resources.html">기타 단순 값도</a> 같은 방식으로
+동작합니다. 예를 들면 색상은 다음과 같습니다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;color name="yellow">#f00&lt;/color>
+ &lt;color name="highlight">@color/red&lt;/color>
+&lt;/resources>
+</pre>
+
+
+
+
+<h2 id="Compatibility">리소스와 연관된 최선의 기기 호환성 제공</h2>
+
+<p>애플리케이션이 여러 기기 구성을 지원하게 하려면,
+언제나 애플리케이션이 사용하는 각 유형의 리소스에 기본 리소스를 제공하는 것이 매우 중요합니다.</p>
+
+<p>예를 들어 애플리케이션이 여러 언어를 지원할 경우, 항상 <em>언어 및 지역 한정자</em> <a href="#LocaleQualifier">없이</a> {@code
+values/} 디렉터리(여기에 문자열 저장)를 포함시켜야 합니다. 그렇게 하지 않고 언어와 지역 한정자가 있는 디렉터리에
+모든 문자열을 넣으면, 문자열이 지원하지 않는 언어로 설정된 기기에서 애플리케이션을
+실행하면 작동이 중단됩니다. 그러나 기본
+{@code values/} 리소스를 제공하는 한은 애플리케이션이 제대로 실행됩니다(사용자가 이해하지 못하는
+언어로라도 작동합니다. 작동 중단보다 낫습니다.)</p>
+
+<p>마찬가지로 화면 방향에 기초하여 여러 가지 레이아웃 리소스를 제공하는 경우
+하나의 방향을 기본값으로 선택해야 합니다. 예를 들어 가로 방향에는 {@code
+layout-land/}로, 세로 방향에는 {@code layout-port/}로 레이아웃 리소스를 제공하는 대신 하나를 기본으로 남겨두십시오.
+가로 방향에 {@code layout/}, 세로 방향에 {@code layout-port/}와 같은 식으로 하면 됩니다.</p>
+
+<p>애플리케이션이 예상치 못한 구성에서 실행될 수 있을 뿐만 아니라
+Android의 새 버전에서 이전 버전에서는 지원하지 않는 구성 한정자를 추가할 수도 있으므로,
+기본 리소스를 제공하는 것이 중요합니다. 새 리소스 한정자를 사용하지만,
+Android 이전 버전과 코드 호환성은 유지한 경우, 그 후 Android 이전 버전이
+애플리케이션을 실행하면 새로운 한정자로 이름을 지정한 리소스를 사용할 수 없으므로 기본 리소스를 제공하지 않으면
+애플리케이션 작동이 중단됩니다. 예를 들어, <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a>이 4로 설정되고 <a href="#NightQualifier">야간 모드</a>(API 레벨 8에서 추가된 {@code night} 또는 {@code notnight})를 사용하는 모든 드로어블 리소스를 한정할 경우, API 레벨 4 기기는
+드로어블 리소스에 액세스하지 못하고 사용이 중단됩니다. 이 경우,
+{@code notnight}를 기본 리소스로 제공하는 것이 좋습니다. 그래야 해당 한정자를 배제하고
+드로어블 리소스가 {@code drawable/} 또는 {@code drawable-night/}이 됩니다.</p>
+
+<p>그러므로 최선의 기기 호환성을 제공하려면 언제나
+애플리케이션에서 반드시 제대로 수행해야 하는 리소스에 대해 기본 리소스를 제공하십시오. 그런 다음 구성 한정자를 사용하여
+특정 기기 구성에 대해 대체 리소스를 생성하면 됩니다.</p>
+
+<p>이 규칙에는 한 가지 예외가 있습니다. 애플리케이션의 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> 이 4 이상이면
+<a href="#DensityQualifier">화면 밀도</a> 한정자로 대체 드로어블 리소스를 제공할 때 기본 드로어블
+리소스가 <em>없어도 됩니다</em>. 기본
+드로어블 리소스가 없더라도 Android가 대체 화면 화질 중에서 가장 잘 맞는 리소스를 찾고
+필요에 따라 비트맵을 축소합니다. 그러나 모든 유형의 기기에서 최상의 경험을 제공하려면,
+모든 세 가지 유형의 밀도에 대해 대체 드로어블을 제공해야 합니다.</p>
+
+
+
+<h2 id="BestMatch">Android가 가장 잘 일치하는 리소스를 찾는 방법</h2>
+
+<p>개발자가 자신이 대체를 제공하는 리소스를 요청하면 Android가 런타임에 어느 대체 리소스를
+사용할지 현대 기기 구성에 따라 여러 가지로 선택합니다. Android가
+대체 리소스를 선택하는 방법을 보여주기 위해 다음 드로어블 디렉터리에 각각 같은 이미지의
+서로 다른 버전이 들어있다고 가정하겠습니다.</p>
+
+<pre class="classic no-pretty-print">
+drawable/
+drawable-en/
+drawable-fr-rCA/
+drawable-en-port/
+drawable-en-notouch-12key/
+drawable-port-ldpi/
+drawable-port-notouch-12key/
+</pre>
+
+<p>그리고 기기 구성은 다음과 같다고 가정해봅시다.</p>
+
+<p style="margin-left:1em;">
+로케일 = <code>en-GB</code> <br/>
+화면 방향 = <code>port</code> <br/>
+화면 픽셀 밀도 = <code>hdpi</code> <br/>
+터치 스크린 유형 = <code>notouch</code> <br/>
+기본 텍스트 입력 메서드 = <code>12key</code>
+</p>
+
+<p>Android는 기기 구성을 이용 가능한 대체 리소스와 비교하여,
+{@code drawable-en-port}에서 드로어블을 선택합니다.</p>
+
+<p>시스템은 다음과 같은 논리에 따라
+어느 리소스를 사용할지 결정합니다.</p>
+
+
+<div class="figure" style="width:371px">
+<img src="{@docRoot}images/resources/res-selection-flowchart.png" alt="" height="471" />
+<p class="img-caption"><strong>그림 2.</strong> Android가 가장 잘 일치하는 리소스를 찾는 방법을 나타낸
+흐름도입니다.</p>
+</div>
+
+
+<ol>
+ <li>기기 구성과 충돌하는 리소스 파일을 제거합니다.
+ <p><code>drawable-fr-rCA/</code>는
+<code>en-GB</code> 로케일과 충돌하므로 제거되었습니다.</p>
+<pre class="classic no-pretty-print">
+drawable/
+drawable-en/
+<strike>drawable-fr-rCA/</strike>
+drawable-en-port/
+drawable-en-notouch-12key/
+drawable-port-ldpi/
+drawable-port-notouch-12key/
+</pre>
+<p class="note"><strong>예외:</strong> 화면 픽셀 밀도 한정자 하나만은 충돌을 이유로 제거되지
+않습니다. 기기의 화면 밀도가 hdpi라도,
+현 시점에서는 모든 화면 밀도가 일치로 간주되므로 <code>drawable-port-ldpi/</code>를 제거하지 않습니다.
+ 자세한 정보는 <a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a> 문서에서 이용하실 수 있습니다.</p></li>
+
+ <li>목록(<a href="#table2">표2</a>)에서 (그 다음으로) 우선 순위가 가장 높은 한정자를 선택합니다
+(MCC부터 시작하여 아래로 내려가십시오). </li>
+ <li>리소스 디렉터리 중에 이 한정자를 포함한 것이 있나요? </li>
+ <ul>
+ <li>없는 경우, 2단계로 돌아가 다음 한정자를 살펴보십시오 (이 예시의 경우
+언어 한정자에 도달할 때까지 답은 "없습니다"입니다).</li>
+ <li>있는 경우, 4단계로 계속 진행합니다.</li>
+ </ul>
+ </li>
+
+ <li>이 한정자를 포함하지 않는 디렉터리를 제거합니다. 이 예시에서는 시스템이
+언어 한정자를 포함하지 않는 디렉터리를 모두 제거합니다.</li>
+<pre class="classic no-pretty-print">
+<strike>drawable/</strike>
+drawable-en/
+drawable-en-port/
+drawable-en-notouch-12key/
+<strike>drawable-port-ldpi/</strike>
+<strike>drawable-port-notouch-12key/</strike>
+</pre>
+<p class="note"><strong>예외:</strong> 문제의 한정자가 화면 픽셀 밀도라면,
+Android는 기기 화면 밀도와 가장 가깝게 일치하는 옵션을 선택합니다.
+일반적으로, Android는 작은 원본 이미지를 확대하는 것보다
+큰 원본 이미지를 축소하는 것을 선호합니다. <a href="{@docRoot}guide/practices/screens_support.html">다중 화면
+지원</a>을 참조하십시오.</p>
+ </li>
+
+ <li>뒤로 돌아가 디렉터리가 한 개만 남을 때까지 2, 3 및 4단계를 반복합니다. 이 예시에서, 일치하는 것이 있는 다음 한정자는
+화면 방향입니다.
+그러므로 화면 방향을 지정하지 않는 리소스가 제거됩니다.
+<pre class="classic no-pretty-print">
+<strike>drawable-en/</strike>
+drawable-en-port/
+<strike>drawable-en-notouch-12key/</strike>
+</pre>
+<p>남은 디렉터리는 {@code drawable-en-port}입니다.</p>
+ </li>
+</ol>
+
+<p>이 절차는 요청된 각 리소스에 대해 실행하지만, 시스템이 몇 가지 측면을 추가로
+최적화합니다. 그러한 최적화 가운데에는 일단 기기 구성을 알게 되고 나면 절대 일치할 가능성이 없는
+대체 리소스를 시스템이 제거할 수 있다는 점도 있습니다. 예를 들어, 구성 언어가
+영어("en")이고 영어 이외의 다른 언어 한정자로 설정된 리소스 디렉터리는
+절대 확인된 리소스 풀에 포함되지 않습니다(
+언어 한정자가 포함되지 <em>않는</em> 리소스 디렉터리는 여전히 포함됩니다).</p>
+
+<p>화면 크기 한정자에 기초하여 리소스를 선택할 때 시스템은 가장 잘 일치하는 리소스가 없다면
+현재 화면보다 작은 화면에 지정된 리소스를 사용합니다
+(예를 들어, 큰 화면은 필요에 따라 일반 크기 화면 리소스를 사용합니다). 그러나
+이용 가능한 리소스가 현재 화면보다 <em>큰</em> 리소스뿐이라면, 시스템은
+이를 사용하지 <strong>않고</strong>, 기기 구성에 일치하는 리소스가 없으면 애플리케이션 사용이 중단됩니다
+(예를 들어 모든 레이아웃 리소스가 {@code xlarge} 한정자에 태그되어 있지만,
+기기가 보통 크기 화면일 경우).</p>
+
+<p class="note"><strong>참고:</strong> 한정자의 <em>우선 순위</em>(<a href="#table2">표 2</a> 참조)가 기기와 정확하게 일치하는
+한정자 수보다 더 중요합니다. 예를 들어 위의 4단계에서
+목록의 마지막 선택에 기기와 정확히 일치하는 한정자가 세 개 포함되어 있지만(방향, 터치 스크린
+유형 및 입력 메서드), <code>drawable-en</code>에는 일치하는 매개변수가
+하나뿐입니다(언어). 다만, 언어가 이러한 다른 한정자보다 우선 순위가 높기 때문에
+<code>drawable-port-notouch-12key</code>는 탈락합니다.</p>
+
+<p>애플리케이션에서 리소스를 사용하는 것에 대한 자세한 정보는 <a href="accessing-resources.html">리소스 액세스</a>로 계속 진행하여 알아보십시오.</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/resources/runtime-changes.jd b/docs/html-intl/intl/ko/guide/topics/resources/runtime-changes.jd
new file mode 100644
index 000000000000..a5e7f5bbad88
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/resources/runtime-changes.jd
@@ -0,0 +1,281 @@
+page.title=런타임 변경 처리하기
+page.tags=액티비티, 수명 주기
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#RetainingAnObject">구성 변경 중에 객체 보존하기</a></li>
+ <li><a href="#HandlingTheChange">구성 변경 직접 처리하기</a>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="providing-resources.html">리소스 제공</a></li>
+ <li><a href="accessing-resources.html">리소스 액세스</a></li>
+ <li><a href="http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html">더 빠른
+ 화면 방향 변경</a></li>
+ </ol>
+</div>
+</div>
+
+<p>몇몇 기기 구성은 런타임 중에 변경될 수 있습니다
+(예: 화면 방향, 키보드 가용성 및 언어 등). 그러한 변경이 일어나는 경우,
+Android는 실행 중인
+{@link android.app.Activity}를 다시 시작합니다({@link android.app.Activity#onDestroy()} 호출, 뒤이어 {@link
+android.app.Activity#onCreate(Bundle) onCreate()} 호출). 이런 동작은 여러분이 제공한
+대체 리소스로 애플리케이션을 자동으로 다시 로딩함으로써 새로운 기기 구성에 애플리케이션이 적응하는 것을 돕도록
+설계되었습니다(예: 다양한 화면 방향과 크기에 대한 다양한 레이아웃).</p>
+
+<p>다시 시작을 적절히 처리하려면 액티비티가 정상적인
+<a href="{@docRoot}guide/components/activities.html#Lifecycle">액티비티
+수명 주기</a>를 통해 이전 상태를 복원하는 것이 중요합니다. 여기에서 Android는
+{@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()}를 호출한 다음에 액티비티를 소멸시켜
+애플리케이션 상태에 대한 데이터를 저장할 수 있습니다. 그러면
+{@link android.app.Activity#onCreate(Bundle) onCreate()} 또는 {@link
+android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()} 중에 상태를 복원할 수 있습니다.</p>
+
+<p>애플리케이션이 애플리케이션 상태를 그대로 유지한 채 스스로 다시 시작할 수 있는지 시험해 보려면,
+구성 변경을 일으켜보아야 합니다(예를 들어 화면 방향 변경 등). 이는 애플리케이션에서 여러 가지 작업을 수행하는
+동안 해봅니다. 애플리케이션이 언제든 사용자 데이터나 상태를 손실하지 않고
+다시 시작할 수 있어야 합니다. 그래야 구성 변경과 같은 이벤트를 처리할 수 있기 때문입니다. 그렇지 않으면
+사용자가 걸려오는 전화를 받은 다음 한참 후에 애플리케이션으로 돌아오면 애플리케이션 프로세스가 이미
+소멸되어 있을 수 있습니다. 액티비티 상태를 복원하는 방법을 배우려면, <a href="{@docRoot}guide/components/activities.html#Lifecycle">액티비티 수명 주기</a>에 관해 읽어보십시오.</p>
+
+<p>하지만, 애플리케이션을 다시 시작하고 상당량의 데이터를 복원하면 비용도 많이 들고
+불량한 사용자 환경이 만들어지는 상황에 직면할 수도 있습니다. 그러한 상황이라면,
+두 가지 다른 옵션이 있습니다.</p>
+
+<ol type="a">
+ <li><a href="#RetainingAnObject">구성 변경 중에 객체 보존하기</a>
+ <p>구성이 변경되는 중에 액티비티가 다시 시작될 수 있게 허용하되, 액티비티의 새 인스턴스에 상태
+저장 객체를 넣습니다.</p>
+
+ </li>
+ <li><a href="#HandlingTheChange">구성 변경 직접 처리하기</a>
+ <p>특정 구성 변경 중에 시스템이 액티비티를 다시 시작하도록 하지 못하게 방지하되,
+구성이 실제로 변경되면 콜백을 수신하도록 하여 필요에 따라 액티비티를 수동으로 업데이트할 수
+있도록 합니다.</p>
+ </li>
+</ol>
+
+
+<h2 id="RetainingAnObject">구성 변경 중에 객체 보존하기</h2>
+
+<p>액티비티를 다시 시작하려면 많은 수의 데이터 세트를 복구해야 하는 경우, 네트워크 연결을
+다시 설정하거나 다른 집약적 작업을 수행한 다음 완전히 다시 시작하십시오.
+구성 변경 때문에 사용자 환경이 느려질 수 있습니다. 또한, 액티비티 상태를 완전히 복원하려면
+{@link android.os.Bundle}을 사용할 수도 있습니다. 이것은 시스템이 개발자 대신 {@link
+android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} 콜백으로 저장해두는 것입니다. 이것은 대형 객체(예: 비트맵)를 담도록
+디자인된 것이 아니며 이 안의 데이터는 반드시 직렬화했다가 다시 역직렬화해야 합니다. 이렇게 하면
+메모리를 아주 많이 소모할 수 있으며 구성 변경이 느려질 수 있습니다. 이와 같은 상황에서는
+액티비티를 다시 초기화해야 한다는 부담을 해결하기 위해 액티비티가 구성 변경으로 인해 다시 시작되었을 때 {@link
+android.app.Fragment}를 보존하면 됩니다. 이 프래그먼트에는
+보존하고자 하는 상태 저장 객체에 대한 참조를 담을 수 있습니다.</p>
+
+<p>Android 시스템이 구성 변경으로 인하여 액티비티를 종료시킬 때, 액티비티에서 보존하기로 표시해둔
+프래그먼트는 소멸되지 않습니다. 그러한 프래그먼트를 액티비티에 추가하면
+상태 저장 객체를 보존할 수 있습니다.</p>
+
+<p>런타임 구성 변경 중에 상태 저장 객체를 프래그먼트에 보존해두는 방법은 다음과 같습니다.</p>
+
+<ol>
+ <li>{@link android.app.Fragment} 클래스를 확장하고 상태 저장
+객체에 참조를 선언합니다.</li>
+ <li>프래그먼트가 생성되면 {@link android.app.Fragment#setRetainInstance(boolean)}를 호출합니다.
+ </li>
+ <li>해당 프래그먼트를 액티비티에 추가합니다.</li>
+ <li>{@link android.app.FragmentManager}를 사용하여 액티비티가 다시 시작될 때 프래그먼트를
+검색합니다.</li>
+</ol>
+
+<p>예를 들어 프래그먼트를 다음과 같이 정의합니다.</p>
+
+<pre>
+public class RetainedFragment extends Fragment {
+
+ // data object we want to retain
+ private MyDataObject data;
+
+ // this method is only called once for this fragment
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // retain this fragment
+ setRetainInstance(true);
+ }
+
+ public void setData(MyDataObject data) {
+ this.data = data;
+ }
+
+ public MyDataObject getData() {
+ return data;
+ }
+}
+</pre>
+
+<p class="caution"><strong>주의:</strong> 어느 객체든 저장할 수 있지만,
+{@link android.app.Activity}에 묶여 있는 객체는 절대로 전달하면 안 됩니다. 예를 들어 {@link
+android.graphics.drawable.Drawable}, {@link android.widget.Adapter}, {@link android.view.View}
+ 또는 {@link android.content.Context}와 연관된 기타 모든 객체가 이에 해당됩니다. 이런 것을 전달하면,
+원래 액티비티 인스턴스의 모든 보기와 리소스를 몽땅 누출시킵니다. (리소스 누출이란
+애플리케이션이 리소스에 대한 보유권을 유지하고 있어 가비지 수집의 대상이 될 수 없고, 따라서 엄청난 양의 메모리가
+손실된다는 뜻입니다.)</p>
+
+<p>그런 다음 {@link android.app.FragmentManager}를 사용하여 프래그먼트를 액티비티에 추가합니다.
+프래그먼트에서 데이터 객체를 가져오려면 런타임 구성 변경 중에 액티비티가 다시 시작될 때
+가져오면 됩니다. 예를 들어, 액티비티를 다음과 같이 정의합니다.</p>
+
+<pre>
+public class MyActivity extends Activity {
+
+ private RetainedFragment dataFragment;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // find the retained fragment on activity restarts
+ FragmentManager fm = getFragmentManager();
+ dataFragment = (DataFragment) fm.findFragmentByTag(“data”);
+
+ // create the fragment and data the first time
+ if (dataFragment == null) {
+ // add the fragment
+ dataFragment = new DataFragment();
+ fm.beginTransaction().add(dataFragment, “data”).commit();
+ // load the data from the web
+ dataFragment.setData(loadMyData());
+ }
+
+ // the data is available in dataFragment.getData()
+ ...
+ }
+
+ &#64;Override
+ public void onDestroy() {
+ super.onDestroy();
+ // store the data in the fragment
+ dataFragment.setData(collectMyLoadedData());
+ }
+}
+</pre>
+
+<p>이 예시에서 {@link android.app.Activity#onCreate(Bundle) onCreate()}는 프래그먼트를 추가하거나
+이에 대한 참조를 복원합니다. {@link android.app.Activity#onCreate(Bundle) onCreate()} 또한
+프래그먼트 인스턴스 안에 상태 저장 객체를 저장합니다.
+{@link android.app.Activity#onDestroy() onDestroy()}는 보존된
+프래그먼트 인스턴스 내부의 상태 저장 객체를 업데이트합니다.</p>
+
+
+
+
+
+<h2 id="HandlingTheChange">구성 변경 직접 처리하기</h2>
+
+<p>애플리케이션이 특정 구성 변경 중에 리소스를 업데이트하지 않아도 되고
+그와 <em>동시에</em> 성능 한계가 있어 액티비티 다시 시작을 피해야 하는 경우,
+액티비티가 구성 변경을 알아서 처리한다고 선언하면 됩니다.
+이렇게 하면 시스템이 액티비티를 다시 시작하지 않도록 방지할 수 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 구성 변경을 직접 처리하면 대체 리소스를 사용하는 것이
+훨씬 더 까다로워질 수 있습니다. 시스템이 개발자 대신 자동으로 이를 적용해주지 않기
+때문입니다. 이 기법은 구성 변경으로 인한 재시작을 반드시 피해야만 하는 경우 최후의 수단으로서만
+고려해야 하며 대부분의 애플리케이션에는 권장하지 않습니다.</p>
+
+<p>액티비티가 구성 변경을 직접 처리한다고 선언하려면, 매니페스트 파일의 적절한 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> 요소를 편집하여
+처리하고자 하는 구성을 나타내는 값이 있는 <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> 속성을 포함하도록
+합니다. 가능한 값은 <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> 속성에 대한 관련 문서에 목록으로 나열되어 있습니다(가장 보편적으로 사용되는 값은 화면 방향이 변경될 때 다시 시작을 방지하는 {@code "orientation"}과
+키보드 가용성이 변경될 때 다시 시작을 방지하는 {@code "keyboardHidden"}
+입니다). 이 속성에는 여러 개의 구성 값을 선언할 수 있습니다. 각각을
+파이프 {@code |} 문자로 구분하면 됩니다.</p>
+
+<p>예를 들어 다음 매니페스트 코드는 화면 방향 변경과 키보드 가용성 변경을 둘 다
+처리하는 액티비티를 선언하는 것입니다.</p>
+
+<pre>
+&lt;activity android:name=".MyActivity"
+ android:configChanges="orientation|keyboardHidden"
+ android:label="@string/app_name">
+</pre>
+
+<p>이제 이러한 구성 중 하나가 변경되어도 {@code MyActivity}는 다시 시작하지 않습니다.
+그 대신, {@code MyActivity}가 {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}로의 호출을 받습니다. 이 메서드는
+{@link android.content.res.Configuration} 객체로 전달되며, 이는 새 기기 구성을
+나타냅니다. {@link android.content.res.Configuration}의 필드를 읽어보면
+새 구성을 판별할 수 있고 적절한 변경을 할 수 있습니다. 그러려면 인터페이스에 사용된 리소스를
+업데이트하면 됩니다. 이 메서드가
+호출되면, 액티비티의 {@link android.content.res.Resources} 객체가
+업데이트되어 새 구성에 기반한 리소스를 반환하며, 따라서 시스템이 액티비티를 다시 시작하지 않아도
+UI의 요소를 손쉽게 재설정할 수 있게 됩니다.</p>
+
+<p class="caution"><strong>주의:</strong> Android 3.2(API 레벨 13)부터 기기가
+세로 방향 및 가로 방향 사이를 전환할 때 <strong>"화면 크기"도
+같이 변경됩니다</strong>. 따라서,
+API 레벨 13 이상(<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> 및 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
+ 속성에서 선언한 내용에 따름)을 대상으로 개발하는 경우 방향 변경으로 인한 런타임 다시 시작을 방지하고자 하면, {@code
+"orientation"} 값 외에 {@code "screenSize"} 값도 포함시켜야 합니다. 다시 말해, {@code
+android:configChanges="orientation|screenSize"}를 선언해야 합니다. 하지만, 애플리케이션이 API 레벨 12 이하를
+대상으로 하는 경우라면 애플리케이션이 언제든 이 구성 변경을 알아서 처리합니다(이 구성 변경은
+액티비티를 다시 시작하지 않습니다. 이는 Android 3.2 이상 기기에서 실행되는 경우에도 마찬가지입니다).</p>
+
+<p>예를 들어, 다음 {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} 구현은
+현재 기기의 방향을 확인합니다.</p>
+
+<pre>
+&#64;Override
+public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ // Checks the orientation of the screen
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
+ } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
+ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
+ }
+}
+</pre>
+
+<p>{@link android.content.res.Configuration} 객체는 변경된 것만이 아니라 현재
+구성 전체를 나타냅니다. 대부분의 경우에는 구성이 정확히 어떻게
+변경되었는지에는 관심이 없고 처리 중인 구성에 대체 리소스를 제공하는 모든 리소스를 그저
+재할당하기만 하면 됩니다. 예를 들어 이제 {@link
+android.content.res.Resources} 객체가 업데이트되었으니 {@link android.widget.ImageView#setImageResource(int)
+setImageResource()}가 있는 모든
+{@link android.widget.ImageView}와
+새 구성에 대한 적절한 리소스를 재설정할 수 있습니다(<a href="providing-resources.html#AlternateResources">리소스 제공</a>에 설명된 바와 같음).</p>
+
+<p>{@link
+android.content.res.Configuration} 필드에서 가져온 값이
+{@link android.content.res.Configuration} 클래스에서 가져온 특정 상수와 일치하는 정수라는 점을 눈여겨 보십시오. 각 필드에
+어느 상수를 써야 하는지에 대한 관련 문서는 {@link
+android.content.res.Configuration} 참조에 있는 적절한 필드를 참조하십시오.</p>
+
+<p class="note"><strong>명심할 점:</strong> 액티비티가 직접 구성 변경을 처리한다고 선언하는 경우,
+대체를 제공하는 모든 요소에 대해 본인이 직접 책임을 지게 됩니다. 액티비티가 직접
+방향 변경을 처리하고 가로 및 세로 방향 사이에서 바뀌어야 하는 이미지가 있는 경우,
+각 리소스를 각 요소에 재할당해야 하며 이를 {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} 중에 수행해야 합니다.</p>
+
+<p>이러한 구성 변경을 기반으로 애플리케이션을 업데이트하지 않아도 되는 경우,
+대신 {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}를 구현하지 <em>않으면</em> 됩니다. 이런
+경우, 구성 변경 전에 쓰였던 리소스가 모두 그대로 사용되고 액티비티의 다시 시작만
+피한 것이 됩니다. 그러나, 애플리케이션은
+언제든 종료되고 이전 상태를 그대로 유지한 채 다시 시작될 수 있어야 합니다 정상적인 액티비티
+수명 주기 중에 상태 유지에서의 탈출 방안으로 이 기법을 고려해서는 안 됩니다. 이는 애플리케이션이
+다시 시작되지 않도록 방지할 수 없는, 다른 구성 변경도 여럿 있어서일뿐만 아니라, 사용자가
+애플리케이션을 떠났을 경우 해당 사용자가 다시 돌아오기 전에 소멸되는 것과 같은 이벤트를 처리해야 하기 때문이라는
+이유도 있습니다.</p>
+
+<p>액티비티 내에서 처리할 수 있는 구성 변경이 무엇인지에 대한 자세한 내용은 <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> 관련 문서와 {@link android.content.res.Configuration}
+클래스를 참조하십시오.</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/controls.jd b/docs/html-intl/intl/ko/guide/topics/ui/controls.jd
new file mode 100644
index 000000000000..bf873980beb6
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/controls.jd
@@ -0,0 +1,90 @@
+page.title=입력 제어
+parent.title=사용자 인터페이스
+parent.link=index.html
+@jd:body
+
+<div class="figure" style="margin:0">
+ <img src="{@docRoot}images/ui/ui-controls.png" alt="" style="margin:0" />
+</div>
+
+<p>입력 제어는 앱의 사용자 인터페이스에 있는 대화형 구성 요소입니다.
+Android는 버튼, 텍스트 필드, 찾기 막대, 확인란, 확대 버튼, 전환 버튼 등과 같이
+UI에서 사용할 수 있도록 매우 다양한 제어를 제공합니다.</p>
+
+<p>UI에 입력 제어를 추가하려면 단순히 <a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML 레이아웃</a>에 XML 요소를 하나 추가하기만 하면 됩니다.
+다음은 텍스트 필드와 버튼이 있는 레이아웃을 예시로 나타낸 것입니다.</p>
+
+<pre style="clear:right">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="horizontal">
+ &lt;EditText android:id="@+id/edit_message"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="@string/edit_message" />
+ &lt;Button android:id="@+id/button_send"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_send"
+ android:onClick="sendMessage" />
+&lt;/LinearLayout>
+</pre>
+
+<p>각 입력 제어는 특정한 입력 이벤트를 지원하므로, 사용자가 텍스트를 입력할 때 또는 버튼을 터치할 때
+이벤트를 처리할 수 있게 해줍니다.</p>
+
+
+<h2 id="CommonControls">보편적인 제어</h2>
+<p>다음은 앱에서 사용할 수 있는 몇 가지 보편적인 제어를 목록으로 나열한 것입니다. 링크를 따라가면 각 제어에 대해
+좀 더 자세히 알아볼 수 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> Android는 여기에 나열된 것보다 몇 가지 더 많은 제어를 제공합니다.
+ 더 많은 내용을 알아보려면 {@link android.widget} 패키지를 탐색해보십시오.
+앱에 특정한 종류의 입력 제어가 필요한 경우, 나름의 <a href="{@docRoot}guide/topics/ui/custom-components.html">사용자 지정 구성 요소</a>를 직접 구축해도 됩니다.</p>
+
+<table>
+ <tr>
+ <th scope="col">제어 유형</th>
+ <th scope="col">설명</th>
+ <th scope="col">관련 클래스</th>
+ </tr>
+ <tr>
+ <td><a href="controls/button.html">버튼</a></td>
+ <td>사용자가 누르거나 클릭하여 작업을 수행할 수 있는 누름 버튼입니다.</td>
+ <td>{@link android.widget.Button Button} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/text.html">텍스트 필드</a></td>
+ <td>편집 가능한 텍스트 필드입니다. <code>AutoCompleteTextView</code> 위젯을 사용하면 자동 완성 제안을 제공하는 텍스트 입력 위젯을 만들 수 있습니다.</td>
+ <td>{@link android.widget.EditText EditText}, {@link android.widget.AutoCompleteTextView}</td>
+ </tr>
+ <tr>
+ <td><a href="controls/checkbox.html">확인란</a></td>
+ <td>사용자가 전환할 수 있는 켜기/끄기 스위치입니다. 확인란은 사용자에게 선택 가능한 옵션 그룹을 제시할 때 사용합니다. 이들 옵션은 상호 배타적이지 않아야 합니다.</td>
+ <td>{@link android.widget.CheckBox CheckBox} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/radiobutton.html">무선 버튼</a></td>
+ <td>확인란과 비슷하지만, 예외가 있다면 그룹 내에서 하나만 선택할 수 있다는 점입니다.</td>
+ <td>{@link android.widget.RadioGroup RadioGroup}
+ <br>{@link android.widget.RadioButton RadioButton} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/togglebutton.html" style="white-space:nowrap">전환 버튼</a></td>
+ <td>조명 표시기가 있는 켜기/끄기 버튼입니다.</td>
+ <td>{@link android.widget.ToggleButton ToggleButton} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/spinner.html">회전자</a></td>
+ <td>드롭다운 목록으로, 이것을 사용하면 사용자가 주어진 집합에서 하나의 값을 선택할 수 있습니다.</td>
+ <td>{@link android.widget.Spinner Spinner} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/pickers.html">선택기</a></td>
+ <td>사용자를 위한 대화로, 위/아래 버튼을 사용하거나 스와이프 동작을 사용하여 주어진 집합에 대한 하나의 값을 선택할 수 있게 해줍니다. 날짜(월, 일, 연도) 값을 입력하려면 <code>DatePicker</code>코드&gt; 위젯을 사용하면 되고, 아니면 시간(시, 분, 오전/오후) 값을 입력하는 데 <code>TimePicker</code> 위젯을 사용해도 됩니다. 이렇게 하면 사용자의 로케일에 맞게 자동으로 형식을 설정합니다.</td>
+ <td>{@link android.widget.DatePicker}, {@link android.widget.TimePicker}</td>
+ </tr>
+</table>
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/declaring-layout.jd b/docs/html-intl/intl/ko/guide/topics/ui/declaring-layout.jd
new file mode 100644
index 000000000000..78832368b222
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/declaring-layout.jd
@@ -0,0 +1,492 @@
+page.title=레이아웃
+page.tags=view,viewgroup
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#write">XML 쓰기</a></li>
+ <li><a href="#load">XML 리소스 로딩</a></li>
+ <li><a href="#attributes">속성</a>
+ <ol>
+ <li><a href="#id">ID</a></li>
+ <li><a href="#layout-params">레이아웃 매개변수</a></li>
+ </ol>
+ </li>
+ <li><a href="#Position">레이아웃 위치</a></li>
+ <li><a href="#SizePaddingMargins">크기, 안쪽 여백 및 여백</a></li>
+ <li><a href="#CommonLayouts">보편적인 레이아웃</a></li>
+ <li><a href="#AdapterViews">어댑터로 레이아웃 구축하기</a>
+ <ol>
+ <li><a href="#FillingTheLayout">데이터로 어댑터 보기 채우기</a></li>
+ <li><a href="#HandlingUserSelections">클릭 이벤트 처리</a></li>
+ </ol>
+ </li>
+</ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.view.View}</li>
+ <li>{@link android.view.ViewGroup}</li>
+ <li>{@link android.view.ViewGroup.LayoutParams}</li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/firstapp/building-ui.html">간단한 사용자
+인터페이스 구축</a></li> </div>
+</div>
+
+<p>레이아웃은 사용자 인터페이스에 대한 시각적 구조를 정의합니다. 예컨대 <a href="{@docRoot}guide/components/activities.html">액티비티</a> 또는 <a href="{@docRoot}guide/topics/appwidgets/index.html">앱 위젯</a>에 대한 UI가 이에 해당됩니다.
+레이아웃을 선언하는 데에는 다음과 같은 두 가지 방법이 있습니다.</p>
+<ul>
+<li><strong>UI 요소를 XML로 선언</strong>. Android가 위젯과 레이아웃 등과 같이
+보기 클래스와 하위 클래스에 상응하는 간단한 XML 어휘를 제공합니다.</li>
+<li><strong>런타임에 레이아웃 요소를 인스턴트화</strong>. 애플리케이션이
+ 프로그래밍 방법으로 보기 및 ViewGroup객체를 만들 수 있습니다(그리고 그 속성을 조작하기도 합니다). </li>
+</ul>
+
+<p>Android 프레임워크에서는 이와 같이 애플리케이션의 UI를 선언하고 관리하기 위한 메서드를 둘 중 하나만, 또는 둘 모두 사용할 수 있는 유연성을 부여합니다. 예를 들어, 애플리케이션의 기본 레이아웃을 XML로 선언하면서 그 안에 나타날 화면 요소와 그 속성을 포함할 수 있습니다. 그러면 이제 애플리케이션에 코드를 추가하여 화면 객체의 상태를 수정하도록 할 수 있으며, 여기에는 런타임에 XML로 선언된 것도 포함됩니다. </p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <ul>
+ <li><a href="{@docRoot}tools/sdk/eclipse-adt.html">Eclipse용 ADT
+ 플러그인</a>이 XML의 레이아웃 미리보기를 제공합니다. &mdash;
+XML 파일이 열린 상태에서 <strong>레이아웃</strong> 탭을 선택하십시오.</li>
+ <li>또한,
+<a href="{@docRoot}tools/debugging/debugging-ui.html#hierarchyViewer">계층 뷰어</a> 도구로
+레이아웃 디버깅도 시도해 보아야 합니다.&mdash;이것은 레이아웃 속성 값을 드러내고,
+내부 여백/여백 표시기가 있는 와이어프레임을 그리며 개발자가 에뮬레이터 또는 기기에서 디버깅하는 동안
+완전히 렌더링된 보기를 제공합니다.</li>
+ <li><a href="{@docRoot}tools/debugging/debugging-ui.html#layoutopt">layoutopt</a> 도구를
+ 사용하면 레이아웃과 계층을 비효율성 또는 다른 문제에 대하여 재빨리 분석할 수 있게 해줍니다.</li>
+</div>
+</div>
+
+<p>UI를 XML로 선언하는 것의 이점은 이렇게 하면 애플리케이션을 그 행동을 제어하는 코드로부터 따로 표시하기가 더 좋다는 것입니다. UI 설명은 애플리케이션 코드의 외부에 있습니다. 이는 다시 말해 소스 코드를 수정하고 다시 컴파일링하지 않아도 이를 수정 또는 변경할 수 있다는 뜻입니다. 예를 들어, 서로 다른 화면 방향, 사로 다른 기기 화면 크기 및 서로 다른 언어에 대해 XML 레이아웃을 생성할 수 있습니다. 이외에도 레이아웃을 XML로 선언하면 UI의 구조를 시각화하기가 더 쉬우므로 문제를 디버깅하기도 더 쉽습니다. 따라서, 이 문서는 레이아웃을 XML로 선언하는 방법을 가르치는 데 주안점을 두고 있습니다. 런타임에 보기 객체를 인스턴트화하는 것에 흥미가 있는 경우,
+{@link android.view.ViewGroup} 및
+{@link android.view.View} 클래스 참조를 참조하십시오.</p>
+
+<p>일반적으로 UI 요소를 선언하는 데 쓰이는 XML 어휘는 클래스와 메서드 명명을 충실히 따릅니다. 여기에서 요소 이름은 클래스 이름에 상응하며 속성 이름은 메서드에 상응합니다. 사실 이러한 일치성은 아주 직접적인 경우가 잦아 어느 XML 속성이 클래스 메서드에 상응하는지를 추측할 수 있고, 어느 클래스가 주어진 XML 요소에 상응하는지도 추측할 수 있습니다. 다만 모든 어휘가 다 같지는 않다는 점을 유의하십시오. 몇몇 경우에는 명명에 약간의 차이점이 있습니다. 예를 들어,
+EditText 요소에는 <code>text</code> 속성이 있으며 이는
+<code>EditText.setText()</code>에 상응합니다. </p>
+
+<p class="note"><strong>팁:</strong> 여러 가지 레이아웃 유형에 대해서는 <a href="{@docRoot}guide/topics/ui/layout-objects.html">보편적인
+레이아웃 객체</a>를 참조하십시오. 여러 가지 레이아웃을 구축하는 데 대한 튜토리얼 모음도 있습니다.
+<a href="{@docRoot}resources/tutorials/views/index.html">Hello 보기</a> 튜토리얼 가이드를 참조하십시오.</p>
+
+<h2 id="write">XML 쓰기</h2>
+
+<p>Android의 XML 어휘를 사용하면 UI 레이아웃과 그 안에 들어있는 화면 요소를 HTML에서 웹 페이지를 디자인할 때와 같은 방식으로 신속하게 디자인할 수 있습니다. 즉 일련의 중첩된 요소를 사용하는 것입니다. </p>
+
+<p>각 레이아웃 파일에는 반드시 딱 하나의 루트 요소만 있어야 하며, 이는 보기 또는 ViewGroup 객체여야 합니다. 루트 요소를 정의했으면, 하위 요소로 더 많은 레이아웃 요소 또는 위젯을 추가하여 점층적으로 레이아웃을 정의할 보기 계층을 구축할 수 있습니다. 예를 들어, 다음은 수직 {@link android.widget.LinearLayout}을
+ 사용하여 {@link android.widget.TextView} 및 {@link android.widget.Button}을 보유하는 XML 레이아웃을 나타낸 것입니다.</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+ &lt;TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello, I am a TextView" />
+ &lt;Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello, I am a Button" />
+&lt;/LinearLayout>
+</pre>
+
+<p>레이아웃을 XML로 선언하고 나면 그 파일을 Android 프로젝트의 <code>res/layout/</code> 디렉터리 내에
+<code>.xml</code> 확장자로 저장하여 적절하게 컴파일링되도록 합니다. </p>
+
+<p>레이아웃 XML 파일의 구문에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/resources/layout-resource.html">레이아웃 리소스</a> 문서에서 확인할 수 있습니다.</p>
+
+<h2 id="load">XML 리소스 로딩</h2>
+
+<p>애플리케이션을 컴파일링하는 경우, 각 XML 레이아웃 파일이
+{@link android.view.View} 리소스 안에 컴파일링됩니다. 애플리케이션 코드로부터 가져온 레이아웃 리소스는
+{@link android.app.Activity#onCreate(android.os.Bundle) Activity.onCreate()} 콜백
+구현에 로딩해야 합니다.
+이렇게 하려면 <code>{@link android.app.Activity#setContentView(int) setContentView()}</code>를 호출한 다음, 이를
+<code>R.layout.<em>layout_file_name</em></code> 형태로 레이아웃 리소스의 참조에 전달합니다.
+ 예를 들어, XML 레이아웃이 <code>main_layout.xml</code>로 저장된 경우, 이것을 액티비티에 대해 로딩하려면
+다음과 같이 하면 됩니다.</p>
+<pre>
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main_layout);
+}
+</pre>
+
+<p>액티비티 내의 <code>onCreate()</code> 콜백 메서드는 액티비티가 시작될 때
+Android 프레임워크가 호출합니다(수명 주기에 대한 논의는
+<a href="{@docRoot}guide/components/activities.html#Lifecycle">액티비티</a>
+ 문서에서 확인하십시오).</p>
+
+
+<h2 id="attributes">속성</h2>
+
+<p>모든 보기 및 ViewGroup 객체는 각자 나름대로의 다양한 XML 속성을 지원합니다.
+몇몇 속성은 보기 객체에만 특화되어 있지만(예를 들어, TextView는 <code>textSize</code>
+속성을 지원), 이와 같은 속성은 이 클래스를 확장할 수 있는 모든 보기 객체가 상속하기도 합니다.
+모든 보기 객체에 공통으로 쓰이는 것도 몇 가지 있습니다. 왜냐하면 이들은 루트 보기 클래스에서 상속된 것이기 때문입니다(예:
+<code>id</code> 속성). 그리고 나머지 속성은 "레이아웃 매개변수"로 간주됩니다.
+이들은 보기 객체의 특정한 레이아웃 방향을 설명하는 것으로, 이는 해당 객체의 상위 VeiwGroup 객체에서
+정의된 바에 따릅니다.</p>
+
+<h3 id="id">ID</h3>
+
+<p>모든 보기 객체에는 연관된 정수 ID가 있을 수 있습니다. 이는 트리 내에서 해당 보기를 고유하게 식별하기 위한 것입니다.
+애플리케이션이 컴파일링되면 이 ID가 정수로 참조되지만, ID는
+일반적으로 레이아웃 XML 파일에 문자열로 할당되며, <code>id</code> 속성으로 쓰입니다.
+이것은 모든 보기 객체에 공통적인 XML 속성으로
+({@link android.view.View} 클래스가 정의) 이것을 매우 자주 사용하게 됩니다.
+ID에 대한, XML 태그 내에 있는 구문은 다음과 같습니다.</p>
+<pre>android:id="&#64;+id/my_button"</pre>
+
+<p>문자열 시작 부분에 있는 앳 기호(@)는 XML 파서가 ID 문자열의 나머지를 구문 분석하고 확장하여
+ID 리소스로 식별해야 한다는 것을 나타냅니다. 더하기 기호(+)는 이것이 새 리소스 이름이며,
+이것을 반드시 생성하여 우리 리소스에 추가해야 한다는 것을 뜻합니다(<code>R.java</code> 파일에서). Android 프레임워크는 다른 ID 리소스도 아주 많이
+제공합니다. Android 리소스 ID를 참조할 때에는 더하기 기호는 필요하지 않지만
+<code>android</code> 패키지 네임스페이스를 다음과 같이 반드시 추가해야 합니다.</p>
+<pre>android:id="&#64;android:id/empty"</pre>
+<p><code>android</code> 패키지 네임스페이스를 제자리에 넣으면 이제 ID를 로컬 리소스 클래스에서가 아니라 <code>android.R</code>
+ 리소스 클래스에서 참조하고 있는 것이 됩니다.</p>
+
+<p>보기를 생성하고 이를 애플리케이션에서 참조하는 데 쓰이는 보편적인 패턴은 다음과 같습니다.</p>
+<ol>
+ <li>레이아웃 파일에서 보기/위젯을 정의한 다음 이를 고유한 ID에 할당합니다.
+<pre>
+&lt;Button android:id="&#64;+id/my_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="&#64;string/my_button_text"/>
+</pre>
+ </li>
+ <li>그런 다음 보기 객체의 인스턴스를 생성하고 이를 레이아웃에서 캡처합니다
+(일반적으로 <code>{@link android.app.Activity#onCreate(Bundle) onCreate()}</code> 메서드에서).
+<pre>
+Button myButton = (Button) findViewById(R.id.my_button);
+</pre>
+ </li>
+</ol>
+<p>{@link android.widget.RelativeLayout}을 생성할 때에는 보기 객체의 ID를 정의하는 것이 중요합니다.
+관계 레이아웃에서는 형제 보기가 또 다른 형제 보기와 관련된 자신의 레이아웃을 정의할 수 있으며,
+이를 고유한 ID로 참조하게 됩니다.</p>
+<p>ID는 트리 전체를 통틀어 고유할 필요는 없지만, 트리에서 검색하고 있는 부분 내에서는
+고유해야 합니다(이것이 트리 전체인 경우가 잦으므로, 가급적이면 완전히
+고유한 것을 쓰는 것이 가장 좋습니다).</p>
+
+
+<h3 id="layout-params">레이아웃 매개변수</h3>
+
+<p><code>layout_<em>something</em></code>이라는 XML 레이아웃 속성이
+보기가 상주하는 ViewGroup에 대해 적절한 보기의 레이아웃 매개변수를 정의합니다.</p>
+
+<p>모든 ViewGroup 클래스가 중첩된 클래스를 하나씩 구현하며 이것이 {@link
+android.view.ViewGroup.LayoutParams}를 확장합니다. 이 하위 클래스에는
+각 하위 보기의 크기와 위치를 보기 그룹에 적절한 방식으로 정의하는
+속성 유형이 들어 있습니다. 그림 1에서 볼 수 있듯이, 상위 보기 그룹이
+각 하위 보기의 레이아웃 매개변수를 정의합니다(하위 보기 그룹 포함).</p>
+
+<img src="{@docRoot}images/layoutparams.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 각 보기와 연관된 레이아웃 매개변수가
+있는 보기 계층을 시각화한 것입니다.</p>
+
+<p>모든 LayoutParams 하위 클래스에는 설정 값에 대한 각기 자신만의 구문이 있다는 점을
+눈여겨 보십시오. 각 하위 요소는 자신의 상위에 적합한 LayoutParams를 정의해야 합니다.
+다만 이것은 자신의 하위에 대해 각기 다른 LayoutParams도 정의할 수 있습니다. </p>
+
+<p>모든 보기 그룹에는 너비와 높이가 포함되며(<code>layout_width</code> 및
+<code>layout_height</code>), 각 보기는 이들을 반드시 정의해야 합니다. 선택 사항으로
+여백과 테두리도 포함하는 LayoutParams도 많습니다. <p>
+
+<p>너비와 높이는 정확한 치수로 지정할 수 있습니다. 다만 이것은 자주 하지
+않는 것이 좋습니다. 그보다는 다음과 같은 상수 중 하나를 사용하여 너비 또는 높이를 설정하는 경우가
+더 많습니다. </p>
+
+<ul>
+ <li><var>wrap_content</var> 보기에 콘텐츠에 필요한 치수대로 알아서
+크기를 조정하라고 합니다.</li>
+ <li><var>match_parent</var> (다른 이름은 <var>fill_parent</var> 로, API 레벨 8 이전에 해당)
+보기에 상위 보기 그룹이 허용하는 한 최대한으로 커지라고 합니다.</li>
+</ul>
+
+<p>일반적으로 픽셀과 같이 절대적인 단위를 사용하여 레이아웃 너비와 높이를 지정하는 것은
+권장하지 않습니다. 그 대신, 밀도 독립적인 픽셀 단위와 같이 상대적인 측정치를
+사용하는 것(<var>dp</var>), <var>wrap_content</var>, 또는
+<var>match_parent</var>등이 더 낫습니다. 이렇게 하면
+애플리케이션이 다양한 기기 화면 크기에 걸쳐서도 적절하게 표시되도록 보장하는 데 도움이 되기 때문입니다.
+허용된 측정 유형은
+<a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">
+사용 가능한 리소스</a>에 정의되어 있습니다.</p>
+
+
+<h2 id="Position">레이아웃 위치</h2>
+ <p>
+ 보기의 모양은 직사각형입니다. 보기에는 위치가 있으며, 이는
+ 한 쌍의 <em>왼쪽</em> 및 <em>상단</em> 좌표, 그리고 두 개의 치수가 너비와 높이를 나타내는
+형식으로 표현됩니다. 위치와 치수의 단위는 픽셀입니다.
+
+ </p>
+
+ <p>
+ 보기의 위치를 검색할 수 있습니다.
+{@link android.view.View#getLeft()} 및 {@link android.view.View#getTop()} 메서드를 호출하면 됩니다. 전자는 보기를
+나타내는 직사각형의 왼쪽, 즉 X 좌표를 반환합니다. 후자는 보기를
+나타내는 직사각형의 상단, 즉 Y 좌표를 반환합니다. 이들 메서드는 둘 다
+보기의 위치를 해당 보기의 상위와 관련지어 반환합니다. 예를 들어,
+<code>getLeft()</code>가 20을 반환하는 경우 이는 해당 보기가 그 보기의 바로 상위의 왼쪽 가장자리에서
+오른쪽으로 20픽셀 떨어진 곳에 있다는 뜻입니다.
+ </p>
+
+ <p>
+ 이외에도 불필요한 계산을 피하기 위해 여러 가지 편의 메서드가 제공됩니다.
+구체적으로 {@link android.view.View#getRight()} 및 {@link android.view.View#getBottom()}을 들 수 있습니다.
+ 이들 메서드는 해당 보기를 나타내는 직사각형의 오른쪽과 하단 가장자리의 좌표를 반환합니다.
+ 예를 들어 {@link android.view.View#getRight()}를
+ 호출하는 것은 다음 계산과 비슷합니다. <code>getLeft() + getWidth()</code>
+ </p>
+
+
+<h2 id="SizePaddingMargins">크기, 안쪽 여백 및 여백</h2>
+ <p>
+ 보기의 크기는 너비와 높이로 표현됩니다. 사실 하나의 보기는
+두 쌍의 너비 및 높이 값을 소유합니다.
+ </p>
+
+ <p>
+ 첫 번째 쌍을 <em>측정된 너비</em> 및
+<em>측정된 높이</em>라고 합니다. 이들 치수는 보기가
+상위 내에서 얼마나 커지고자 하는지를 정의합니다. 측정된
+치수를 가져오려면 {@link android.view.View#getMeasuredWidth()}
+ 및 {@link android.view.View#getMeasuredHeight()}를 호출하면 됩니다.
+ </p>
+
+ <p>
+ 두 번째 쌍은 단순히 <em>너비</em> 및 <em>높이</em>라고 일컬으며,
+때로는 <em>그리기 너비</em> 및 <em>그리기 높이</em>로 부를 때도 있습니다. 이러한
+치수는 그리기 시간 및 레이아웃 후에 보기가 화면에 표시되는 실제 크기를
+정의합니다. 이들 값은 측정된 너비 및 높이와 달라도 되지만
+꼭 달라야 하는 것은 아닙니다. 너비와 높이를 가져오려면
+{@link android.view.View#getWidth()} 및 {@link android.view.View#getHeight()}를 호출하면 됩니다.
+ </p>
+
+ <p>
+ 보기의 치수를 측정하려면 보기는 자신의 안쪽 여백을 감안합니다. 안쪽 여백은
+보기의 왼쪽, 상단, 오른쪽 및 하단 부분에 대해 픽셀로 표시됩니다.
+ 안쪽 여백은 정해진 픽셀 수를 사용하여 보기의 콘텐츠를 오프셋하는 데 쓰일 수도
+있습니다. 예를 들어 왼쪽 안쪽 여백을 2로 설정하면 해당 보기의 콘텐츠를 왼쪽 가장자리에서
+오른쪽으로 2픽셀 밀어냅니다. 안쪽 여백을 설정할 때에는
+{@link android.view.View#setPadding(int, int, int, int)} 메서드를 사용하면 되고, 이를 쿼리하려면
+{@link android.view.View#getPaddingLeft()}, {@link android.view.View#getPaddingTop()},
+{@link android.view.View#getPaddingRight()} 및 {@link android.view.View#getPaddingBottom()}을 사용하면 됩니다.
+ </p>
+
+ <p>
+ 보기가 안쪽 여백을 정의할 수는 있지만, 여백에 대한 지원은 전혀 제공하지
+않습니다. 다만 보기 그룹이 그와 같은 지원을 제공합니다. 자세한 정보는
+{@link android.view.ViewGroup} 및
+{@link android.view.ViewGroup.MarginLayoutParams}를 참조하십시오.
+ </p>
+
+ <p>치수에 대한 자세한 정보는
+<a href="{@docRoot}guide/topics/resources/more-resources.html#Dimension">치수 값</a>을 참조하십시오.
+ </p>
+
+
+
+
+
+
+<style type="text/css">
+div.layout {
+ float:left;
+ width:200px;
+ margin:0 0 20px 20px;
+}
+div.layout.first {
+ margin-left:0;
+ clear:left;
+}
+</style>
+
+
+
+
+<h2 id="CommonLayouts">보편적인 레이아웃</h2>
+
+<p>{@link android.view.ViewGroup} 클래스의 각 하위 클래스는 각기 고유한 방식으로 자신 안에
+중첩한 보기를 표시합니다. 아래는 Android 플랫폼에서 기본 제공되는, 보다 보편적인 레이아웃 유형을
+몇 가지 나타낸 것입니다.</p>
+
+<p class="note"><strong>참고:</strong> 하나 이상의 레이아웃을 또 다른 레이아웃에 중첩하여
+UI 디자인을 이룰 수도 있지만, 레이아웃 계층을 가능한 한 얕게 유지하도록
+애써야 합니다. 중첩된 레이아웃이 적을수록 레이아웃이 더욱 빠르게 그려집니다(가로로 넓은 보기 계층이
+깊은 보기 계층보다 낫습니다).</p>
+
+<!--
+<h2 id="framelayout">FrameLayout</h2>
+<p>{@link android.widget.FrameLayout FrameLayout} is the simplest type of layout
+object. It's basically a blank space on your screen that you can
+later fill with a single object &mdash; for example, a picture that you'll swap in and out.
+All child elements of the FrameLayout are pinned to the top left corner of the screen; you cannot
+specify a different location for a child view. Subsequent child views will simply be drawn over
+previous ones,
+partially or totally obscuring them (unless the newer object is transparent).
+</p>
+-->
+
+
+<div class="layout first">
+ <h4><a href="layout/linear.html">선형 레이아웃</a></h4>
+ <a href="layout/linear.html"><img src="{@docRoot}images/ui/linearlayout-small.png" alt="" /></a>
+ <p>여러 하위를 하나의 가로 방향 또는 세로 방향 행으로 정리하는 레이아웃. 이것은
+창의 길이가 화면 길이를 웃도는 경우 스크롤 막대를 만듭니다.</p>
+</div>
+
+<div class="layout">
+ <h4><a href="layout/relative.html">관계 레이아웃</a></h4>
+ <a href="layout/relative.html"><img src="{@docRoot}images/ui/relativelayout-small.png" alt="" /></a>
+ <p>여러 하위 객체의 위치를 서로 관련지어 나타내거나(하위 A가
+하위 B의 왼쪽), 상위와 관련지어 나타낼 수 있도록 해줍니다(상위의 맨 위에 맞춰 정렬).</p>
+</div>
+
+<div class="layout">
+ <h4><a href="{@docRoot}guide/webapps/webview.html">웹 보기</a></h4>
+ <a href="{@docRoot}guide/webapps/webview.html"><img src="{@docRoot}images/ui/webview-small.png" alt="" /></a>
+ <p>웹 페이지를 표시합니다.</p>
+</div>
+
+
+
+
+<h2 id="AdapterViews" style="clear:left">어댑터로 레이아웃 구축하기</h2>
+
+<p>레이아웃의 콘텐츠가 동적이거나 미리 정의되지 않은 경우,
+{@link android.widget.AdapterView}의 하위 클래스가 되는 레이아웃을 사용하여 런타임에 보기로 레이아웃을 채울 수 있습니다.
+{@link android.widget.AdapterView} 클래스의 하위 클래스는 {@link android.widget.Adapter}를
+사용하여 자신의 레이아웃에 데이터를 바인딩합니다. {@link android.widget.Adapter}가 데이터 소스와 {@link android.widget.AdapterView}
+ 레이아웃 사이의 중개자 역할을 합니다. &mdash;{@link android.widget.Adapter}가
+ 데이터를 검색하여(배열 또는 데이터베이스 쿼리와 같은 소스로부터)
+각 항목을 보기로 변환해서 {@link android.widget.AdapterView} 레이아웃에 추가될 수 있도록 합니다.</p>
+
+<p>어댑터로 지원되는 보편적인 레이아웃의 몇 가지 예는 다음과 같습니다.</p>
+
+<div class="layout first">
+ <h4><a href="layout/listview.html">목록 보기</a></h4>
+ <a href="layout/listview.html"><img src="{@docRoot}images/ui/listview-small.png" alt="" /></a>
+ <p>스크롤로 내리는 하나의 열 목록을 표시합니다.</p>
+</div>
+
+<div class="layout">
+ <h4><a href="layout/gridview.html">눈금 보기</a></h4>
+ <a href="layout/gridview.html"><img src="{@docRoot}images/ui/gridview-small.png" alt="" /></a>
+ <p>스크롤로 내리는 열과 행의 눈금을 표시합니다.</p>
+</div>
+
+
+
+<h3 id="FillingTheLayout" style="clear:left">데이터로 어댑터 보기 채우기</h3>
+
+<p>{@link android.widget.ListView} 또는
+{@link android.widget.GridView}와 같은 {@link android.widget.AdapterView}를 채우려면 {@link android.widget.AdapterView} 인스턴스를
+{@link android.widget.Adapter}에 바인딩하면 됩니다. 이는 외부 소스로부터 데이터를 검색하여 각 데이터 항목을 나타내는 {@link
+android.view.View}를 생성합니다.</p>
+
+<p>Android는 {@link android.widget.Adapter}의 하위 클래스를 여러 개 제공합니다.
+이는 여러 가지 종류의 데이터를 검색하고 {@link android.widget.AdapterView}에 대한 보기를 구축하는 데 유용합니다.
+가장 보편적인 어댑터 두 가지를 예로 들면 다음과 같습니다.</p>
+
+<dl>
+ <dt>{@link android.widget.ArrayAdapter}</dt>
+ <dd>이 어댑터는 데이터 소스가 배열일 때 사용하십시오. 기본적으로 {@link
+android.widget.ArrayAdapter}가 각 항목에서 {@link
+java.lang.Object#toString()}를 호출하고 그 콘텐츠를 {@link
+android.widget.TextView}에 배치함으로써 각 배열 항목에 대한 보기를 생성합니다.
+ <p>예를 들어, {@link
+android.widget.ListView}로 문자열 배열을 표시하고자 하는 경우, 생성자를 사용하여
+새로운 {@link android.widget.ArrayAdapter}를 초기화해서 각 문자열과 문자열 배열에 대한 레이아웃을 지정하면 됩니다.</p>
+<pre>
+ArrayAdapter&lt;String> adapter = new ArrayAdapter&lt;String>(this,
+ android.R.layout.simple_list_item_1, myStringArray);
+</pre>
+<p>이 생성자에 대한 인수는 다음과 같습니다.</p>
+<ul>
+ <li>개발자의 앱 {@link android.content.Context}</li>
+ <li>배열에 있는 각 문자열에 대한 {@link android.widget.TextView}가 들어있는 레이아웃</li>
+ <li>문자열 배열</li>
+</ul>
+<p>그런 다음 {@link android.widget.ListView}에서
+{@link android.widget.ListView#setAdapter setAdapter()}를 호출하기만 하면 됩니다.</p>
+<pre>
+ListView listView = (ListView) findViewById(R.id.listview);
+listView.setAdapter(adapter);
+</pre>
+
+ <p>각 항목의 외관을 사용자 지정하려면 배열의 객체에 대한 {@link
+java.lang.Object#toString()} 메서드를 재정의하면 됩니다. 아니면, 각 항목에 대하여
+{@link android.widget.TextView}가 아닌 다른 보기를 생성하고자 하는 경우(예를 들어 각 배열 항목에
+{@link android.widget.ImageView}를 원하는 경우), {@link
+android.widget.ArrayAdapter} 클래스를 확장하고 {@link android.widget.ArrayAdapter#getView
+getView()}를 재정의하여 각 항목에 대해 원하는 유형의 보기를 반환하도록 할 수 있습니다.</p>
+
+</dd>
+
+ <dt>{@link android.widget.SimpleCursorAdapter}</dt>
+ <dd>이 어댑터는 데이터 출처가 {@link android.database.Cursor}일 때 사용하십시오.
+{@link android.widget.SimpleCursorAdapter}를 사용하는 경우,
+{@link android.database.Cursor}에 있는 각 행에 대하여 사용할 레이아웃을 지정해야 합니다. 또한 {@link android.database.Cursor}
+의 어느 열이 레이아웃의 어느 보기에 삽입되어야 할지도 지정해야 합니다. 예를 들어 사람 이름과
+전화번호로 이루어진 목록을 생성하고자 하는 경우, 각 사람에 대해 행이 하나씩 있고 이름과 번호에 대해 열이 들어있는 {@link
+android.database.Cursor}를 반환하는 쿼리를 수행하면 됩니다.
+ 그런 다음 레이아웃에서 각 결과에 대하여 {@link
+android.database.Cursor}의 어느 열을 원하는지 지정하는 문자열 배열을 만들 수 있고, 각 열이 배치되어야 하는
+상응하는 보기를 지정하는 정수 배열을 만들면 됩니다.</p>
+<pre>
+String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
+ ContactsContract.CommonDataKinds.Phone.NUMBER};
+int[] toViews = {R.id.display_name, R.id.phone_number};
+</pre>
+<p>{@link android.widget.SimpleCursorAdapter}를 인스턴트화하는 경우, 각 결과에 대해 사용할 레이아웃과
+결과가 들어있는 {@link android.database.Cursor}, 그리고 다음의 두 배열을 전달합니다.</p>
+<pre>
+SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
+ R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
+ListView listView = getListView();
+listView.setAdapter(adapter);
+</pre>
+<p>그러면 {@link android.widget.SimpleCursorAdapter}가
+{@link android.database.Cursor}에 있는 각 행에 대한 보기를 하나씩 생성합니다. 이때 상응하는 {@code toViews} 보기 안에 각 {@code
+fromColumns} 항목을 삽입함으로써 제공된 레이아웃을 사용합니다.</p>.</dd>
+</dl>
+
+
+<p>애플리케이션의 수명이 진행되는 동안에 어댑터가 읽는 기본 데이터를 변경하는 경우,
+{@link android.widget.ArrayAdapter#notifyDataSetChanged()}를 호출해야 합니다.
+이렇게 하면 첨부된 보기에 데이터가 변경되었으며 스스로 새로 고쳐야 한다는 사실을 알려줍니다.</p>
+
+
+
+<h3 id="HandlingUserSelections">클릭 이벤트 처리</h3>
+
+<p>{@link android.widget.AdapterView}에 있는 각 항목에서의 클릭 이벤트에 응답하려면
+{@link android.widget.AdapterView.OnItemClickListener} 인터페이스를 구현하면 됩니다. 예:</p>
+
+<pre>
+// Create a message handling object as an anonymous class.
+private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v, int position, long id) {
+ // Do something in response to the click
+ }
+};
+
+listView.setOnItemClickListener(mMessageClickedHandler);
+</pre>
+
+
+
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/dialogs.jd b/docs/html-intl/intl/ko/guide/topics/ui/dialogs.jd
new file mode 100644
index 000000000000..23e92c9f855e
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/dialogs.jd
@@ -0,0 +1,798 @@
+page.title=대화
+page.tags=alertdialog,dialogfragment
+
+@jd:body
+
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#DialogFragment">대화 프래그먼트 생성</a></li>
+ <li><a href="#AlertDialog">경고 대화 구축</a>
+ <ol>
+ <li><a href="#AddingButtons">버튼 추가</a></li>
+ <li><a href="#AddingAList">목록 추가</a></li>
+ <li><a href="#CustomLayout">사용자 지정 레이아웃 생성</a></li>
+ </ol>
+ </li>
+ <li><a href="#PassingEvents">이벤트를 대화의 호스트에 다시 전달</a></li>
+ <li><a href="#ShowingADialog">대화 표시</a></li>
+ <li><a href="#FullscreenDialog">대화를 전체 화면으로 또는 포함된 프래그먼트로 표시</a>
+ <ol>
+ <li><a href="#ActivityAsDialog">액티비티를 큰 화면에 대화로 표시</a></li>
+ </ol>
+ </li>
+ <li><a href="#DismissingADialog">대화 무시</a></li>
+</ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.app.DialogFragment}</li>
+ <li>{@link android.app.AlertDialog}</li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="{@docRoot}design/building-blocks/dialogs.html">대화 디자인 가이드</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">선택기</a>(날짜/시간 대화)</li>
+ </ol>
+ </div>
+</div>
+
+<p>대화는 사용자에게 결정을 내리거나 추가 정보를 입력하라는
+프롬프트를 보내는 작은 창입니다. 대화는 화면을 가득 채우지 않으며 보통 사용자가
+다음으로 계속 진행하기 전에 조치를 취해야 하는 모달 이벤트에 쓰입니다.</p>
+
+<div class="note design">
+<p><strong>대화 디자인</strong></p>
+ <p>언어 권장 사항을 비롯한 여러 가지 대화 디자인 방법에 관련된 정보는
+<a href="{@docRoot}design/building-blocks/dialogs.html">대화</a> 디자인 가이드를 읽어보십시오.</p>
+</div>
+
+<img src="{@docRoot}images/ui/dialogs.png" />
+
+<p>{@link android.app.Dialog} 클래스가 대화의 기본 클래스이지만,
+{@link android.app.Dialog}를 직접 인스턴트화하는 것은 삼가야 합니다.
+대신 다음 하위 클래스 중 하나를 사용하십시오.</p>
+<dl>
+ <dt>{@link android.app.AlertDialog}</dt>
+ <dd>제목 하나, 최대 세 개의 버튼, 선택 가능한 품목 목록 또는
+사용자 지정 레이아웃을 표시할 수 있는 대화입니다.</dd>
+ <dt>{@link android.app.DatePickerDialog} 또는 {@link android.app.TimePickerDialog}</dt>
+ <dd>미리 정의된 UI가 있는 대화로 사용자로 하여금 날짜 또는 시간을 선택할 수 있게 해줍니다.</dd>
+</dl>
+
+<div class="sidebox">
+<h2>ProgressDialog 피하기</h2>
+<p>Android에는
+{@link android.app.ProgressDialog}라고 하는 또 다른 대화 클래스가 있습니다. 이것은 진행률 표시줄이 있는 대화를 표시하는 것입니다. 그러나,
+로딩이나 확정되지 않은 진행률을 나타내야 하는 경우 이 대신 <a href="{@docRoot}design/building-blocks/progress.html">진행률 및
+액티비티</a>에 대한 디자인 지침을 따르고,
+레이아웃의 {@link android.widget.ProgressBar}를 사용해야 합니다.</p>
+</div>
+
+<p>이러한 클래스가 대화의 스타일과 구조를 정의하지만, 대화의 컨테이너로는
+{@link android.support.v4.app.DialogFragment}를 사용해야 합니다.
+{@link android.support.v4.app.DialogFragment}
+ 클래스는 대화를 만들고 그 외관을 관리하는 데 필요한 모든 제어를 제공합니다.
+{@link android.app.Dialog} 객체에서 메서드를 호출하는 것 대신입니다.</p>
+
+<p>대화를 관리하기 위해 {@link android.support.v4.app.DialogFragment}를 사용하면
+사용자가 <em>뒤로</em> 버튼을 누르거나 화면을 돌릴 때 등
+수명 주기 이벤트를 올바르게 처리하도록 보장할 수 있습니다. {@link
+android.support.v4.app.DialogFragment} 클래스를 사용하면 대화의 UI를 더 큰 UI에
+포함시킬 수 있는 구성 요소로 다시 사용할 수 있게 해주기도 합니다. 이것은 기존의 {@link
+android.support.v4.app.Fragment}와 똑같습니다(대화 UI를 크고 작은 화면에서 서로 다르게
+나타나도록 하고자 하는 경우 등).</p>
+
+<p>이 가이드의 다음 섹션에서는 {@link
+android.support.v4.app.DialogFragment}를 {@link android.app.AlertDialog}
+ 객체와 함께 조합하여 사용하는 방법을 설명합니다. 날짜 또는 시간 선택기를 생성하고자 하는 경우, 대신
+<a href="{@docRoot}guide/topics/ui/controls/pickers.html">선택기</a> 가이드를 읽으십시오.</p>
+
+<p class="note"><strong>참고:</strong>
+{@link android.app.DialogFragment} 클래스는 원래
+Android 3.0(API 레벨 11)에 추가되었기 때문에 이 문서에서는 <a href="{@docRoot}tools/support-library/index.html">지원 라이브러리</a>와 함께 제공된 {@link
+android.support.v4.app.DialogFragment} 클래스를 사용하는 법을 설명합니다. 이 라이브러리를 앱에 추가하면 Android 1.6 이상을 실행하는 기기에서
+{@link android.support.v4.app.DialogFragment}를 비롯하여
+다른 API도 다양하게 사용할 수 있습니다. 앱의 최소 버전이
+API 레벨 11 이상인 경우, {@link
+android.app.DialogFragment}의 프레임워크 버전을 사용해도 되지만, 이 문서에 있는 링크는
+지원 라이브러리 API를 대상으로 한 것이라는 점을 유의하십시오. 지원 라이브러리를 사용할 때에는
+<code>android.support.v4.app.DialogFragment</code>
+ 클래스를 가져와야 합니다. <code>android.app.DialogFragment</code>가 <em>아닙니다</em>.</p>
+
+
+<h2 id="DialogFragment">대화 프래그먼트 생성</h2>
+
+<p>대단히 다양한 대화 디자인을 만들 수 있습니다. 사용자 지정 레이아웃은 물론
+<a href="{@docRoot}design/building-blocks/dialogs.html">대화</a>
+디자인 가이드에서 설명한 것도 포함합니다.
+{@link android.support.v4.app.DialogFragment}를 확장하고 {@link android.support.v4.app.DialogFragment#onCreateDialog
+onCreateDialog()} 콜백 메서드에 {@link android.app.AlertDialog}를
+ 생성하면 됩니다.</p>
+
+<p>예를 들어 다음은 {@link android.app.AlertDialog}로, 이는
+{@link android.support.v4.app.DialogFragment} 내에서 관리되는 것입니다.</p>
+
+<pre>
+public class FireMissilesDialogFragment extends DialogFragment {
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setMessage(R.string.dialog_fire_missiles)
+ .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // FIRE ZE MISSILES!
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ // Create the AlertDialog object and return it
+ return builder.create();
+ }
+}
+</pre>
+
+<div class="figure" style="width:290px;margin:0 0 0 20px">
+<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong>
+메시지 하나와 작업 버튼 두 개가 있는 대화입니다.</p>
+</div>
+
+<p>이 클래스의 인스턴스를 생성하고 해당 객체에서 {@link
+android.support.v4.app.DialogFragment#show show()}를 호출하면 대화는
+그림 1에 표시된 것처럼 나타납니다.</p>
+
+<p>다음 섹션에서는 {@link android.app.AlertDialog.Builder}
+API를 사용하여 대화를 생성하는 것에 대해 좀 더 자세히 설명합니다.</p>
+
+<p>대화가 얼마나 복잡한지에 따라
+{@link android.support.v4.app.DialogFragment}에서 여러 가지 다른 콜백 메서드를 구현할 수 있습니다. 그중에는 기본적인
+<a href="{@docRoot}guide/components/fragments.html#Lifecycle">조각 수명 주기 메서드</a>도 포함됩니다.
+
+
+
+
+
+<h2 id="AlertDialog">경고 대화 구축</h2>
+
+
+<p>{@link android.app.AlertDialog} 클래스를 사용하면
+여러 가지 대화 디자인을 구축할 수 있으며, 필요한 대화 클래스는 이것뿐인 경우도 많습니다.
+그림 2에 표시된 것과 같이 경고 대화에는 세 가지 영역이 있습니다.</p>
+
+<div class="figure" style="width:311px;margin-top:0">
+<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" />
+<p class="img-caption"><strong>그림 2.</strong> 대화의 레이아웃입니다.</p>
+</div>
+
+<ol>
+<li><b>제목</b>
+ <p>이것은 선택 항목이며 콘텐츠 영역에 상세한 메시지, 목록 또는
+사용자 지정 레이아웃이 채워져 있는 경우에만 사용해야 합니다. 단순한 메시지 또는
+질문(그림 1의 대화처럼)을 진술해야 하는 경우, 제목은 없어도 됩니다.</li>
+<li><b>콘텐츠 영역</b>
+ <p>이것은 메시지, 목록 또는 다른 사용자 지정 레이아웃을 표시할 수 있습니다.</p></li>
+<li><b>작업 버튼</b>
+ <p>대화 하나에 작업 버튼은 세 개 이상 있으면 안 됩니다.</p></li>
+</ol>
+
+<p>{@link android.app.AlertDialog.Builder}
+ 클래스가 이와 같은 종류의 콘텐츠가 있는 {@link android.app.AlertDialog}를
+ 생성할 수 있게 해주는 API를 제공하며, 여기에 사용자 지정 레이아웃도 포함됩니다.</p>
+
+<p>{@link android.app.AlertDialog}를 구축하려면 다음과 같이 하면 됩니다.</p>
+
+<pre>
+<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b>
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+<b>// 2. Chain together various setter methods to set the dialog characteristics</b>
+builder.setMessage(R.string.dialog_message)
+ .setTitle(R.string.dialog_title);
+
+<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b>
+AlertDialog dialog = builder.create();
+</pre>
+
+<p>다음 주제는
+{@link android.app.AlertDialog.Builder} 클래스를 사용하여 다양한 대화 속성을 정의하는 방법을 나타낸 것입니다.</p>
+
+
+
+
+<h3 id="AddingButtons">버튼 추가</h3>
+
+<p>그림 2에 표시된 것과 같은 작업 버튼을 추가하려면
+{@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} 및
+{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()} 메서드를 호출하면 됩니다.</p>
+
+<pre style="clear:right">
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+// Add the buttons
+builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User clicked OK button
+ }
+ });
+builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+// Set other dialog properties
+...
+
+// Create the AlertDialog
+AlertDialog dialog = builder.create();
+</pre>
+
+<p><code>set...Button()</code> 메서드에는 버튼의 제목이 필요하고(
+<a href="{@docRoot}guide/topics/resources/string-resource.html">문자열 리소스</a>가 제공), 사용자가 버튼을 눌렀을 때 수행할 작업을 정의하는
+{@link android.content.DialogInterface.OnClickListener}가
+필요합니다.</p>
+
+<p>추가할 수 있는 작업 버튼은 다음과 같은 세 가지가 있습니다.</p>
+<dl>
+ <dt>긍정적</dt>
+ <dd>이것은 수락하고 작업을 계속하는 데 사용해야 합니다("확인(OK)" 작업).</dd>
+ <dt>부정적</dt>
+ <dd>이것은 작업을 취소하는 데 사용해야 합니다.</dd>
+ <dt>중립적</dt>
+ <dd>이것은 사용자가 작업을 계속하고 싶지 않을 수 있지만
+취소하고자 한다고 볼 수 없을 때 사용해야 합니다. 이것은 긍정적 버튼과 부정적 버튼 사이에 나타납니다.
+ 이런 작업을 예로 들면 "나중에 알림" 등이 있습니다.</dd>
+</dl>
+
+<p>{@link
+android.app.AlertDialog}에는 각 버튼 유형을 하나씩만 추가할 수 있습니다. 다시 말해, "긍정적" 버튼이 한 개 이상 있으면 안 됩니다.</p>
+
+
+
+<div class="figure" style="width:290px;margin:0 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_list.png" alt="" />
+<p class="img-caption"><strong>그림 3.</strong>
+제목과 목록이 있는 대화입니다.</p>
+</div>
+
+<h3 id="AddingAList">목록 추가</h3>
+
+<p>{@link android.app.AlertDialog} API와 함께 사용 가능한 목록은 세 가지 종류가 있습니다.</p>
+<ul>
+<li>일반적인 단일 선택 목록</li>
+<li>영구적인 단일 선택 목록(무선 버튼)</li>
+<li>영구적인 다중 선택 목록(확인란)</li>
+</ul>
+
+<p>그림 3에 표시된 것과 같은 단일 선택 목록을 생성하려면
+{@link android.app.AlertDialog.Builder#setItems setItems()} 메서드를 사용하면 됩니다.</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.pick_color)
+ .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // The 'which' argument contains the index position
+ // of the selected item
+ }
+ });
+ return builder.create();
+}
+</pre>
+
+<p>목록은 대화의 콘텐츠 영역에 나타나므로,
+대화는 메시지와 목록을 둘 다 표시할 수 없습니다. 대화에는
+{@link android.app.AlertDialog.Builder#setTitle setTitle()}로 제목을 설정해야 합니다.
+목록에 대한 항목을 지정하려면 {@link
+android.app.AlertDialog.Builder#setItems setItems()}를 호출하여 배열을 하나 전달합니다.
+아니면 {@link
+android.app.AlertDialog.Builder#setAdapter setAdapter()}를 사용하여 목록을 지정해도 됩니다. 이렇게 하면 동적인 데이터가 있는 목록(예: 데이터베이스에서 가져온 것)을
+{@link android.widget.ListAdapter}로 지원할 수 있게 해줍니다.</p>
+
+<p>{@link android.widget.ListAdapter}로 목록을 지원하기로 선택하는 경우,
+항상 {@link android.support.v4.content.Loader}를 사용해야 콘텐츠가 비동기식으로
+로딩됩니다.
+이것은 <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">어댑터로 레이아웃
+구축하기</a> 및 <a href="{@docRoot}guide/components/loaders.html">로더</a>
+ 가이드에 더 자세히 설명되어 있습니다.</p>
+
+<p class="note"><strong>참고:</strong> 기본적으로 목록 항목을 터치하면 대화를 무시하게 됩니다.
+다만 다음과 같은 영구적인 선택 목록 중 하나를 사용하는 경우는 예외입니다.</p>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_checkboxes.png" />
+<p class="img-caption"><strong>그림 4.</strong>
+다중 선택 항목의 목록입니다.</p>
+</div>
+
+
+<h4 id="Checkboxes">영구적 다중 선택 또는 단일 선택 목록 추가</h4>
+
+<p>다중 선택 항목 목록을 추가하거나(확인란)
+단일 선택 목록을 추가하려면(무선 버튼), 각각
+{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
+DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} 또는
+{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
+setSingleChoiceItems()} 메서드를 사용합니다.</p>
+
+<p>예를 들어 다음은 그림 4에 표시된 것과 같이 다중 선택 목록을 생성하는 방법입니다.
+이것은 선택한 항목을
+{@link java.util.ArrayList}에 저장합니다.</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mSelectedItems = new ArrayList(); // Where we track the selected items
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ // Set the dialog title
+ builder.setTitle(R.string.pick_toppings)
+ // Specify the list array, the items to be selected by default (null for none),
+ // and the listener through which to receive callbacks when items are selected
+ .setMultiChoiceItems(R.array.toppings, null,
+ new DialogInterface.OnMultiChoiceClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int which,
+ boolean isChecked) {
+ if (isChecked) {
+ // If the user checked the item, add it to the selected items
+ mSelectedItems.add(which);
+ } else if (mSelectedItems.contains(which)) {
+ // Else, if the item is already in the array, remove it
+ mSelectedItems.remove(Integer.valueOf(which));
+ }
+ }
+ })
+ // Set the action buttons
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ // User clicked OK, so save the mSelectedItems results somewhere
+ // or return them to the component that opened the dialog
+ ...
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ ...
+ }
+ });
+
+ return builder.create();
+}
+</pre>
+
+<p>일반적인 목록과 무선 버튼이 있는 목록 양쪽 모두 "단일 선택" 작업을
+제공하지만, 사용자의 선택을 유지하고자 하는 경우 {@link
+android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
+setSingleChoiceItems()}를 사용해야 합니다.
+다시 말해, 대화를 나중에 다시 여는 경우 사용자의 현재 선택이 무엇인지 나타내야 하며,
+그러면 무선 버튼으로 목록을 생성할 수 있습니다.</p>
+
+
+
+
+
+<h3 id="CustomLayout">사용자 지정 레이아웃 생성</h3>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_custom.png" alt="" />
+<p class="img-caption"><strong>그림 5.</strong> 사용자 지정 대화 레이아웃입니다.</p>
+</div>
+
+<p>대화에서 사용자 지정 레이아웃을 원하는 경우, 레이아웃을 생성한 다음 이를
+{@link android.app.AlertDialog}에 추가하면 됩니다. 이때 {@link
+android.app.AlertDialog.Builder#setView setView()} on your {@link
+android.app.AlertDialog.Builder} 객체를 호출하는 방법을 씁니다.</p>
+
+<p>기본적으로 사용자 지정 레이아웃이 대화창을 가득 채우지만, 여전히
+{@link android.app.AlertDialog.Builder} 메서드를 사용하여 버튼과 제목을 추가할 수 있습니다.</p>
+
+<p>예를 들어 다음은 그림 5에 표시된 대화에 대한 레이아웃 파일입니다.</p>
+
+<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p>
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ &lt;ImageView
+ android:src="@drawable/header_logo"
+ android:layout_width="match_parent"
+ android:layout_height="64dp"
+ android:scaleType="center"
+ android:background="#FFFFBB33"
+ android:contentDescription="@string/app_name" />
+ &lt;EditText
+ android:id="@+id/username"
+ android:inputType="textEmailAddress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_marginBottom="4dp"
+ android:hint="@string/username" />
+ &lt;EditText
+ android:id="@+id/password"
+ android:inputType="textPassword"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_marginBottom="16dp"
+ android:fontFamily="sans-serif"
+ android:hint="@string/password"/>
+&lt;/LinearLayout>
+</pre>
+
+<p class="note"><strong>팁:</strong> 기본적으로 {@link android.widget.EditText}
+ 요소를 설정하여 {@code "textPassword"} 입력 유형을 사용하고자 하는 경우, 글꼴 패밀리가 고정 폭으로 설정되어 있으므로
+글꼴 패밀리를 {@code "sans-serif"}로 변경해야 합니다. 그래야 양쪽 텍스트 필드가 모두 일치하는 글꼴 스타일을
+사용할 수 있습니다.</p>
+
+<p>{@link android.support.v4.app.DialogFragment} 안의 레이아웃을 팽창시키려면,
+{@link android.view.LayoutInflater}를
+{@link android.app.Activity#getLayoutInflater()}로 가져와
+{@link android.view.LayoutInflater#inflate inflate()}를 호출합니다.
+여기서 첫 번째 매개변수가 레이아웃 리소스 ID이고 두 번째 매개변수가 레이아웃의 상위 보기입니다.
+그러므로 그런 다음 {@link android.app.AlertDialog#setView setView()}를
+ 호출하여 레이아웃을 대화에 배치할 수 있습니다.</p>
+
+<pre>
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ // Get the layout inflater
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ // Inflate and set the layout for the dialog
+ // Pass null as the parent view because its going in the dialog layout
+ builder.setView(inflater.inflate(R.layout.dialog_signin, null))
+ // Add action buttons
+ .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ // sign in the user ...
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ LoginDialogFragment.this.getDialog().cancel();
+ }
+ });
+ return builder.create();
+}
+</pre>
+
+<div class="note">
+<p><strong>팁:</strong> 사용자 지정 대화를 원하는 경우,
+{@link android.app.Activity}를 대신 표시해도 됩니다. 이는
+{@link android.app.Dialog} API 대신 대화로 표시하는 것입니다. 단순히 액티비티를 하나 생성한 다음 그 테마를 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> 매니페스트 요소에 있는
+{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog}로
+ 설정하면 됩니다.</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.Dialog" >
+</pre>
+<p>완료되었습니다. 이제 액티비티가 대화를 전체 화면이 아니라 대화창으로 표시합니다.</p>
+</div>
+
+
+
+<h2 id="PassingEvents">이벤트를 대화의 호스트에 다시 전달</h2>
+
+<p>사용자가 대화의 작업 버튼 중 하나를 터치하거나 목록에서 항목을 하나 선택하면,
+{@link android.support.v4.app.DialogFragment}가
+필요한 작업을 알아서 수행할 수도 있지만 대부분의 경우 이벤트를 대화를 연 액티비티 또는 프래그먼트에 직접 전달하고자 할 수 있습니다.
+ 이렇게 하려면 각 클릭 이벤트의 유형별로 메서드가 있는 인터페이스를 정의합니다.
+ 그런 다음 해당 인터페이스를 대화로부터 작업 이벤트를 수신할
+호스트 구성 요소에 구현하면 됩니다.</p>
+
+<p>예를 들어 다음은 인터페이스를 정의하는 {@link android.support.v4.app.DialogFragment}입니다.
+이 인터페이스를 통해 이벤트를 호스트 액티비티에 도로 전달하게 됩니다.</p>
+
+<pre>
+public class NoticeDialogFragment extends DialogFragment {
+
+ /* The activity that creates an instance of this dialog fragment must
+ * implement this interface in order to receive event callbacks.
+ * Each method passes the DialogFragment in case the host needs to query it. */
+ public interface NoticeDialogListener {
+ public void onDialogPositiveClick(DialogFragment dialog);
+ public void onDialogNegativeClick(DialogFragment dialog);
+ }
+
+ // Use this instance of the interface to deliver action events
+ NoticeDialogListener mListener;
+
+ // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
+ &#64;Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Verify that the host activity implements the callback interface
+ try {
+ // Instantiate the NoticeDialogListener so we can send events to the host
+ mListener = (NoticeDialogListener) activity;
+ } catch (ClassCastException e) {
+ // The activity doesn't implement the interface, throw exception
+ throw new ClassCastException(activity.toString()
+ + " must implement NoticeDialogListener");
+ }
+ }
+ ...
+}
+</pre>
+
+<p>대화를 호스팅하는 액티비티는 대화의 인스턴스를 만듭니다.
+이때 대화 프래그먼트의 생성자를 사용하며,
+{@code NoticeDialogListener} 인터페이스 구현을 통해 대화의 이벤트를 수신하게 됩니다.</p>
+
+<pre>
+public class MainActivity extends FragmentActivity
+ implements NoticeDialogFragment.NoticeDialogListener{
+ ...
+
+ public void showNoticeDialog() {
+ // Create an instance of the dialog fragment and show it
+ DialogFragment dialog = new NoticeDialogFragment();
+ dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
+ }
+
+ // The dialog fragment receives a reference to this Activity through the
+ // Fragment.onAttach() callback, which it uses to call the following methods
+ // defined by the NoticeDialogFragment.NoticeDialogListener interface
+ &#64;Override
+ public void onDialogPositiveClick(DialogFragment dialog) {
+ // User touched the dialog's positive button
+ ...
+ }
+
+ &#64;Override
+ public void onDialogNegativeClick(DialogFragment dialog) {
+ // User touched the dialog's negative button
+ ...
+ }
+}
+</pre>
+
+<p>액티비티가 {@code NoticeDialogListener}를 구현하기 때문에&mdash;위에 표시된 {@link android.support.v4.app.Fragment#onAttach onAttach()}
+ 콜백 메서드가 강제 적용&mdash;해당 대화 프래그먼트는
+인터페이스 콜백 메서드를 사용하여 액티비티에 대한 클릭 이벤트를
+전달할 수 있습니다.</p>
+
+<pre>
+public class NoticeDialogFragment extends DialogFragment {
+ ...
+
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Build the dialog and set up the button click handlers
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setMessage(R.string.dialog_fire_missiles)
+ .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // Send the positive button event back to the host activity
+ mListener.onDialogPositiveClick(NoticeDialogFragment.this);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // Send the negative button event back to the host activity
+ mListener.onDialogNegativeClick(NoticeDialogFragment.this);
+ }
+ });
+ return builder.create();
+ }
+}
+</pre>
+
+
+
+<h2 id="ShowingADialog">대화 표시</h2>
+
+<p>대화를 표시하고자 하는 경우, {@link
+android.support.v4.app.DialogFragment}의 인스턴스를 생성한 다음 {@link android.support.v4.app.DialogFragment#show
+show()}를 호출하여 {@link android.support.v4.app.FragmentManager}와 대화 프래그먼트에 대한
+태그 이름을 전달합니다.</p>
+
+<p>{@link android.support.v4.app.FragmentManager}를 가져오려면
+{@link android.support.v4.app.FragmentActivity}에서
+{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()}를 호출하거나 {@link
+android.support.v4.app.Fragment}로부터 {@link
+android.support.v4.app.Fragment#getFragmentManager()}를 호출합니다. 예:</p>
+
+<pre>
+public void confirmFireMissiles() {
+ DialogFragment newFragment = new FireMissilesDialogFragment();
+ newFragment.show(getSupportFragmentManager(), "missiles");
+}
+</pre>
+
+<p>두 번째 인수 {@code "missiles"}는 시스템이
+필요에 따라 프래그먼트의 상태를 저장하고 복원하는 데 사용하는 고유한 태그 이름입니다. 이 태그를 사용하면 {@link android.support.v4.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}를 호출하여 해당 프래그먼트를 파악할 수도 있습니다.
+</p>
+
+
+
+
+<h2 id="FullscreenDialog">대화를 전체 화면으로 또는 포함된 프래그먼트로 표시</h2>
+
+<p>UI 디자인에서, 몇몇 상황 하에서는 UI의 한 조각을 대화로 나타내지만
+다른 상황에서는 전체 화면이나 포함된 프래그먼트로 나타내고자 하는 경우가 있을 수
+있습니다(이는 어쩌면 기기 화면이 대형인지 소형인지에 따라 달라질 수도 있습니다). {@link android.support.v4.app.DialogFragment}
+클래스에서 이런 유연성을 제공하는 것은 이것이 여전히 포함 가능한 {@link
+android.support.v4.app.Fragment} 역할을 할 수 있기 때문입니다.</p>
+
+<p>그러나 이 경우에는 대화를 구축하는 데 {@link android.app.AlertDialog.Builder AlertDialog.Builder}
+또는 다른 {@link android.app.Dialog} 객체를 사용하면 안 됩니다.
+{@link android.support.v4.app.DialogFragment}를 포함 가능한 상태로 만들려면,
+레이아웃 안에 있는 대화의 UI를 정의해야 합니다. 그런 다음 레이아웃을
+{@link android.support.v4.app.DialogFragment#onCreateView
+onCreateView()} 콜백에 로딩합니다.</p>
+
+<p>다음은 대화 또는 포함 가능한 프래그먼트 중 어느 쪽으로든 표시될 수 있는
+{@link android.support.v4.app.DialogFragment} 예시입니다(<code>purchase_items.xml</code>이라는 레이아웃 사용).</p>
+
+<pre>
+public class CustomDialogFragment extends DialogFragment {
+ /** The system calls this to get the DialogFragment's layout, regardless
+ of whether it's being displayed as a dialog or an embedded fragment. */
+ &#64;Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout to use as dialog or embedded fragment
+ return inflater.inflate(R.layout.purchase_items, container, false);
+ }
+
+ /** The system calls this only when creating the layout in a dialog. */
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // The only reason you might override this method when using onCreateView() is
+ // to modify any dialog characteristics. For example, the dialog includes a
+ // title by default, but your custom layout might not need it. So here you can
+ // remove the dialog title, but you must call the superclass to get the Dialog.
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ return dialog;
+ }
+}
+</pre>
+
+<p>그리고 다음은 프래그먼트를 대화로 표시할지 전체 화면 UI로 표시할지 화면 크기를 근거로 결정하는 몇 가지 코드입니다.
+</p>
+
+<pre>
+public void showDialog() {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ CustomDialogFragment newFragment = new CustomDialogFragment();
+
+ if (mIsLargeLayout) {
+ // The device is using a large layout, so show the fragment as a dialog
+ newFragment.show(fragmentManager, "dialog");
+ } else {
+ // The device is smaller, so show the fragment fullscreen
+ FragmentTransaction transaction = fragmentManager.beginTransaction();
+ // For a little polish, specify a transition animation
+ transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ // To make it fullscreen, use the 'content' root view as the container
+ // for the fragment, which is always the root view for the activity
+ transaction.add(android.R.id.content, newFragment)
+ .addToBackStack(null).commit();
+ }
+}
+</pre>
+
+<p>프래그먼트 트랜잭션을 수행하는 것에 대한 자세한 내용은
+<a href="{@docRoot}guide/components/fragments.html">프래그먼트</a> 가이드를 참조하십시오.</p>
+
+<p>이 예시에서는 <code>mIsLargeLayout</code> 부울이 현재 기기가 앱의 큰 레이아웃 디자인을 써야 할지를
+ 나타냅니다(따라서 이 프래그먼트를 전체 화면보다는 대화로 표시).
+ 이런 종류의 부울을 설정하는 가장 좋은 방법은
+<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">부울 리소스 값</a>을
+여러 가지 화면 크기에 대한 <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">대체 리소스</a> 값으로 선언하는 것입니다.
+예를 들어 다음은 여러 가지 화면 크기에 대한 두 가지 버전의 부울 리소스입니다.</p>
+
+<p class="code-caption">res/values/bools.xml</p>
+<pre>
+&lt;!-- Default boolean values -->
+&lt;resources>
+ &lt;bool name="large_layout">false&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p class="code-caption">res/values-large/bools.xml</p>
+<pre>
+&lt;!-- Large screen boolean values -->
+&lt;resources>
+ &lt;bool name="large_layout">true&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p>그러면 액티비티의
+{@link android.app.Activity#onCreate onCreate()} 메서드 중에 {@code mIsLargeLayout} 값을 초기화할 수 있습니다.</p>
+
+<pre>
+boolean mIsLargeLayout;
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
+}
+</pre>
+
+
+
+<h3 id="ActivityAsDialog">액티비티를 큰 화면에 대화로 표시</h3>
+
+<p>작은 화면의 경우 대화를 전체 화면 UI로 표시하는 대신, 큰 화면에 있을 때에는
+{@link android.app.Activity}를 대화로 표시함으로써 같은 결과를 얻을 수 있습니다.
+ 어느 방식을 사용할 것인지는 앱 디자인에 따라 달라지지만,
+액티비티를 대화로 표시하면 앱이 이미 작은 화면용으로 디자인된 상태에서
+태블릿에서의 환경을 개선하기 위해 일시적인 액티비티를 대화로 표시하는 경우
+유용할 때가 많습니다.</p>
+
+<p>큰 화면의 경우 액티비티를 대화로만 표시하려면,
+{@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge}
+ 테마를 <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> 매니페스트 요소에 적용하면 됩니다.</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.DialogWhenLarge" >
+</pre>
+
+<p>액티비티를 여러 가지 테마로 스타일링하는 법에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/ui/themes.html">스타일 및 테마</a> 가이드를 참조하십시오.</p>
+
+
+
+<h2 id="DismissingADialog">대화 무시</h2>
+
+<p>사용자가
+{@link android.app.AlertDialog.Builder}로 생성한 작업 버튼 중 하나라도 터치하면 시스템이 대화를 대신 무시합니다.</p>
+
+<p>시스템은 사용자가 대화 목록에서 항목을 터치하는 경우에도 대화를 무시합니다.
+다만 목록이 무선 버튼이나 확인란을 사용하는 경우에는 예외입니다.
+그렇지 않으면 대화를 수동으로 무시할 수도 있습니다. {@link
+android.support.v4.app.DialogFragment}에서 {@link android.support.v4.app.DialogFragment#dismiss()}를 호출하면 됩니다.</p>
+
+<p>
+대화가 사라질 때 특정 작업을 수행해야 하는 경우, {@link
+android.support.v4.app.DialogFragment}에서 @link
+android.support.v4.app.DialogFragment#onDismiss onDismiss()}를 구현하면 됩니다.</p>
+
+<p>또한 대화를 <em>취소</em>할 수도 있습니다. 이것은 사용자가 작업을 완료하지 않고 대화를
+분명히 떠났다는 것을 나타내는 특수 이벤트입니다. 이것은 사용자가
+<em>뒤로</em> 버튼을 누르거나 대화 영역 바깥의 화면을 터치하거나,
+개발자가 {@link
+android.app.Dialog}에서 명시적으로 {@link android.app.Dialog#cancel()}을 호출한 경우 발생합니다(예: 대화의 "취소" 버튼에 대한 응답으로).</p>
+
+<p>위의 예시에 나타난 바와 같이 취소 이벤트에 응답하려면 {@link
+android.support.v4.app.DialogFragment} 클래스에서
+{@link android.support.v4.app.DialogFragment#onCancel onCancel()}을 구현하면 됩니다.</p>
+
+<p class="note"><strong>참고:</strong> 시스템은
+{@link android.support.v4.app.DialogFragment#onCancel onCancel()} 콜백을 불러오는 이벤트가 발생할 때마다
+{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()}를 호출합니다.
+그러나 {@link android.app.Dialog#dismiss Dialog.dismiss()} 또는 {@link
+android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}를 호출하면
+시스템은 {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()}는 호출하지만 {@link android.support.v4.app.DialogFragment#onCancel onCancel()}은
+호출하지 <em>않습니다</em>. 따라서 사용자가 대화를 보기에서 제거하기 위해 대화에 있는
+<em>긍정적인</em> 버튼을 누르는 경우, 일반적으로 {@link android.support.v4.app.DialogFragment#dismiss dismiss()}를
+사용해야 합니다.</p>
+
+
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/menus.jd b/docs/html-intl/intl/ko/guide/topics/ui/menus.jd
new file mode 100644
index 000000000000..c115c2a7c3ba
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/menus.jd
@@ -0,0 +1,1031 @@
+page.title=메뉴
+parent.title=사용자 인터페이스
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#xml">XML로 메뉴 정의</a></li>
+ <li><a href="#options-menu">옵션 메뉴 만들기</a>
+ <ol>
+ <li><a href="#RespondingOptionsMenu">클릭 이벤트 처리</a></li>
+ <li><a href="#ChangingTheMenu">런타임에 메뉴 항목 변경</a></li>
+ </ol>
+ </li>
+ <li><a href="#context-menu">상황별 메뉴 만들기</a>
+ <ol>
+ <li><a href="#FloatingContextMenu">부동 컨텍스트 메뉴 만들기</a></li>
+ <li><a href="#CAB">상황별 동작 모드 사용</a></li>
+ </ol>
+ </li>
+ <li><a href="#PopupMenu">팝업 메뉴 만들기</a>
+ <ol>
+ <li><a href="#PopupEvents">클릭 이벤트 처리</a></li>
+ </ol>
+ </li>
+ <li><a href="#groups">메뉴 그룹 만들기</a>
+ <ol>
+ <li><a href="#checkable">확인 가능한 메뉴 항목 사용</a></li>
+ </ol>
+ </li>
+ <li><a href="#intents">인텐트에 기반한 메뉴 항목 추가</a>
+ <ol>
+ <li><a href="#AllowingToAdd">다른 메뉴에 액티비티 추가 허용</a></li>
+ </ol>
+ </li>
+</ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.view.Menu}</li>
+ <li>{@link android.view.MenuItem}</li>
+ <li>{@link android.view.ContextMenu}</li>
+ <li>{@link android.view.ActionMode}</li>
+ </ol>
+
+ <h2>참고 항목</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">메뉴 리소스</a></li>
+ <li><a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">
+메뉴 버튼에 작별을 고하세요</a></li>
+ </ol>
+</div>
+</div>
+
+<p>메뉴는 수많은 유형의 애플리케이션에서 사용되는 보편적인 사용자 인터페이스 구성 요소입니다. 친숙하고 일관적인
+사용자 경험을 제공하기 위해 액티비티에서 사용자 작업과 다른 옵션을 제시하는 {@link android.view.Menu} API를
+사용해야 합니다.</p>
+
+<p>Android 3.0(API 레벨 11)부터 Android 구성 기기는
+전용 <em>메뉴</em> 버튼을 하지 않아도 됩니다. 이번 변경 사항부터 Android 앱은
+종래의 6항목 메뉴 패널에 의존하지 않고 작업 모음을 사용하여
+공통 사용자 작업을 표현합니다.</p>
+
+<p>일부 메뉴 항목의 디자인과 사용자 경험이 변경되었지만, 작업과 옵션 세트를 정의하는
+의미 체계 세트는 여전히 {@link android.view.Menu} API를 기초로 사용합니다. 이 가이드는
+모든 버전의 Android에서 세 가지 기본적인 유형의 메뉴나 작업 표시를
+생성하는 법을 보여줍니다.</p>
+
+<dl>
+ <dt><strong>옵션 메뉴 및 작업 모음</strong></dt>
+ <dd><a href="#options-menu">옵션 메뉴</a>는 액티비티에 대한 기본 메뉴 항목 컬렉션
+입니다.
+이곳에 "검색", "이메일 작성" 및 "설정"과 같이 앱에 전체적인 영향을 미치는 작업을 배치해야 합니다.
+ <p>Android 2.3 이하를 대상으로 개발하는 경우 사용자는
+<em>메뉴</em> 버튼을 눌러서 옵션 메뉴 패널을 표시할 수 있습니다.</p>
+ <p>Android 3.0 이상의 경우, 옵션 메뉴의 항목은 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>에서 화면 작업 항목과 오버플로 옵션의 조합으로
+표시됩니다. Android 3.0부터 <em>메뉴</em> 버튼의 사용이 중단되므로(일부
+기기는
+메뉴 버튼이 없습니다), 작업과 다른 옵션에 대한 액세스를 제공하려면 작업 모음을
+사용하기 시작해야 합니다.</p>
+ <p><a href="#options-menu">옵션 메뉴 만들기</a> 섹션을 참조하십시오.</p>
+ </dd>
+
+ <dt><strong>컨텍스트 메뉴 및 상황별 작업 모드</strong></dt>
+
+ <dd>컨텍스트 메뉴는 사용자가 요소를 길게 클릭하면 나타나는 <a href="#FloatingContextMenu">부동 메뉴</a>
+입니다. 이것은 선택한 콘텐츠나 컨텍스트 프레임에
+영향을 주는 작업을 제공합니다.
+ <p>Android 3.0 이상을 대상으로 개발하는 경우, <a href="#CAB">상황별 작업 모드</a>를 사용하여 선택한 콘텐츠의 작업을 활성화해야 합니다. 이 모드는
+화면 위에 있는 막대에서 선택된 콘텐츠에 영향을 미치는 작업 항목을 표시하고 사용자가
+여러 항목을 선택할 수 있습니다.</p>
+ <p><a href="#context-menu">상황별 메뉴 만들기</a>에 관한 섹션을 참조하십시오.</p>
+</dd>
+
+ <dt><strong>팝업 메뉴</strong></dt>
+ <dd>팝업 메뉴는 메뉴를 호출하는 보기에 고정된 수직 목록에서 항목 목록을
+표시합니다. 이것은 정 콘텐츠와 관련이 되는 작업의 오버플로를 제공하거나
+명령의 두 번째 부분에 대한 옵션을 제공하는 데 좋습니다. 팝업 메뉴의 작업은
+해당 콘텐츠에 직접적 영향을 미쳐서는 <strong>안 됩니다</strong>. 이는 상황별 작업의 역할입니다.
+ 팝업 메뉴는 그보다는 티비티의 콘텐츠 영역과 관련이 있는
+확장 작업을 위한 것입니다.
+ <p><a href="#PopupMenu">팝업 메뉴 만들기</a> 섹션을 참조하십시오.</p>
+</dd>
+</dl>
+
+
+
+<h2 id="xml">XML로 메뉴 정의</h2>
+
+<p>모든 메뉴 유형에 대하여, Android는 표준 XML 형식으로 메뉴 항목을 정의합니다.
+액티비티 코드에서 메뉴를 구축하는 대신
+XML <a href="{@docRoot}guide/topics/resources/menu-resource.html">메뉴 리소스</a>에서 메뉴와 모든 항목을 정의해야 합니다. 그러면
+액티비티나 프래그먼트에서 메뉴 리소스를 팽창시킬 수 있습니다({@link android.view.Menu} 개체로 로딩하면 됩니다).
+</p>
+
+<p>메뉴 리소스를 사용하는 것이 좋은 이유로 다음과 같은 몇 가지를 들 수 있습니다.</p>
+<ul>
+ <li>메뉴 구조를 XML로 시작화하면 다른 방식보다 쉽습니다.</li>
+ <li>애플리케이션의 동작 코드에서 메뉴의 콘텐츠를 분리합니다.</li>
+ <li><a href="{@docRoot}guide/topics/resources/index.html">앱 리소스</a> 프레임워크를 활용하여 다양한 플랫폼 버전, 화면 크기 및 기타 구성에 대한
+대체 메뉴 프레임워크를 생성할 수 있습니다.</li>
+</ul>
+
+<p>메뉴를 정의하려면 프로젝트의 <code>res/menu/</code>
+디렉터리에서 XML 파일을 생성하고 다음 요소로 메뉴를 구축합니다.</p>
+<dl>
+ <dt><code>&lt;menu></code></dt>
+ <dd>메뉴 항목의 컨테이너인 {@link android.view.Menu}를 정의합니다.
+<code>&lt;menu></code> 요소는 파일의 루트 노드여야 하고 하나 이상의
+<code>&lt;item></code>와 <code>&lt;group></code> 요소를 보유할 수 있습니다.</dd>
+
+ <dt><code>&lt;item></code></dt>
+ <dd>메뉴 안의 항목 하나를 나타내는 {@link android.view.MenuItem}을 생성합니다.
+이 요소 안에는 하위 메뉴를 생성하기 위한 중첩 <code>&lt;menu></code> 요소가 들어있을 수 있습니다.</dd>
+
+ <dt><code>&lt;group></code></dt>
+ <dd>{@code &lt;item&gt;} 요소를 위한 선택적인 투명 컨테이너입니다. 이것을 사용하면 활성 상태와 가시성 등의 속성을 공유할 수 있도록
+메뉴 항목을 분류하도록 해줍니다.
+자세한 정보를 보려면 <a href="#groups">메뉴 그룹 만들기</a>를 참조하십시오.</dd>
+</dl>
+
+
+<p>다음은 <code>game_menu.xml</code>이라는 메뉴의 예시입니다.</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/new_game"
+ android:icon="@drawable/ic_new_game"
+ android:title="@string/new_game"
+ android:showAsAction="ifRoom"/&gt;
+ &lt;item android:id="@+id/help"
+ android:icon="@drawable/ic_help"
+ android:title="@string/help" /&gt;
+&lt;/menu&gt;
+</pre>
+
+<p><code>&lt;item></code> 요소는 항목의 외관과 동작을
+정의하는 데 사용할 수 있는 여러 속성을 지원합니다. 위 메뉴의 항목에는 다음 속성이 포함되어 있습니다.</p>
+
+<dl>
+ <dt>{@code android:id}</dt>
+ <dd>항목에 고유한 리소스 ID입니다. 사용자가 항목을 선택하면
+애플리케이션이 이것으로 해당 항목을 인식할 수 있게 해줍니다.</dd>
+ <dt>{@code android:icon}</dt>
+ <dd>항목의 아이콘으로 사용할 수 있는 드로어블에 대한 참조입니다.</dd>
+ <dt>{@code android:title}</dt>
+ <dd>항목의 제목으로 사용할 문자열에 대한 참조입니다.</dd>
+ <dt>{@code android:showAsAction}</dt>
+ <dd><a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>에서 작업 항목을 나타낼 시기와 방법을 나타냅니다.</dd>
+</dl>
+
+<p>이들이 여러분이 꼭 사용해야 할 가장 중요한 속성이지만, 사용할 수 있는 요소는 이외에도 많이 있습니다.
+모든 지원 속성에 관한 정보는 <a href="{@docRoot}guide/topics/resources/menu-resource.html">메뉴 리소스</a> 문서를 참조하십시오.</p>
+
+<p>{@code &lt;menu&gt;} 요소를
+{@code &lt;item&gt;}의 요소로 추가하면 어떤 메뉴 항목이든 하위 메뉴를 추가할 수 있습니다(하위 메뉴 제외). 하위 메뉴는 애플리케이션에 PC 애플리케이션의 메뉴 막대(파일,
+편집, 보기 등)의 항목과 같이 주제별로 체계화할 수 있는 기능이 많을 때
+유용합니다. 예:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/file"
+ android:title="@string/file" &gt;
+ &lt;!-- "file" submenu --&gt;
+ &lt;menu&gt;
+ &lt;item android:id="@+id/create_new"
+ android:title="@string/create_new" /&gt;
+ &lt;item android:id="@+id/open"
+ android:title="@string/open" /&gt;
+ &lt;/menu&gt;
+ &lt;/item&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>액티비티에서 메뉴를 사용하려면
+{@link android.view.MenuInflater#inflate(int,Menu)
+MenuInflater.inflate()}를 사용하여 메뉴 리소스를 팽창해야 합니다(XML 리소스를 프로그램 가능 개체로 변환). 다음 섹션에서는 각 메뉴 유형에 대해
+메뉴를 팽창하는 방법을 보여줍니다.</p>
+
+
+
+<h2 id="options-menu">옵션 메뉴 만들기</h2>
+
+<div class="figure" style="width:200px;margin:0">
+ <img src="{@docRoot}images/options_menu.png" height="333" alt="" />
+ <p class="img-caption"><strong>그림 1.</strong> Android 2.3에서 실행되는
+브라우저의 옵션 메뉴입니다.</p>
+</div>
+
+<p>옵션 메뉴에 "검색", "이메일 작성" 및 "설정"과 같이
+현재 액티비티 컨텍스트와 관련이 있는 작업과 다른 옵션을 포함해야 합니다.</p>
+
+<p>화면의 옵션 메뉴에 항목이 나타나는 위치는
+개발자가 애플리케이션을 어느 버전에서 개발했는지에 따라 달라집니다.</p>
+
+<ul>
+ <li><strong>Android 2.3.x(API 레벨 10)
+이하</strong>에서 애플리케이션을 개발했을 경우,
+그림 1과 같이 사용자가 <em>메뉴</em> 버튼을 누르면 화면 아래에 옵션 메뉴의 콘텐츠가 나타납니다. 이것이 열렸을 때 가장 먼저 보이는 부분은
+아이콘
+메뉴이고, 이는 최대 여섯 개의 메뉴 항목을 보유합니다. 메뉴에 여섯 개를 넘는 항목이 포함되어 있는 경우, Android는
+여섯 번째 항목과 나머지 항목을 더보기 메뉴에 배치합니다. 이것은 사용자가
+<em>더보기</em>를 선택하면 열 수 있습니다.</li>
+
+ <li><strong>Android 3.0(API 레벨 11)
+이상</strong>에서 애플리케이션을 개발했을 경우, 옵션 메뉴의 항목은 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>에서 이용할 수 있습니다. 기본적으로 시스템은 모든 항목을 작업 더보기에 배치합니다.
+사용자는 작업 모음 오른쪽에 있는
+작업 더보기 아이콘으로 이를 표시할 수 있습니다(또는 이용할 수 있을 경우 기기 <em>메뉴</em> 버튼을 누르면 됩니다).
+중요한 작업에 대한 빠른 액세스를
+ 활성화하려면
+{@code android:showAsAction="ifRoom"}을 해당 {@code &lt;item&gt;} 요소에 추가하여 몇 가지 항목이 작업 모음에 표시되도록 수준을 올립니다(그림
+2 참조). <p>작업 항목과 다른 작업 모음 동작에 관한 자세한 정보는 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a> 가이드를 참조하십시오. </p>
+<p class="note"><strong>참고:</strong> Andoid 3.0 이상을 대상으로 개발하지 <em>않더라도</em>
+개발자 나름의 작업 모음 레이아웃을 구축하여 비슷한 효과를 낼 수 있습니다. 예를 들어,
+작업 모음이 포함된 Android 이전 버전을 지원하는 방법은 <a href="{@docRoot}resources/samples/ActionBarCompat/index.html">작업 모음 호환성</a>
+샘플을 참조하십시오.</p>
+</li>
+</ul>
+
+<img src="{@docRoot}images/ui/actionbar.png" alt="" />
+<p class="img-caption"><strong>그림 2.</strong> <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb 갤러리</a> 앱의 작업 모음으로
+탐색 탭과 카메라 작업 항목(및 작업 더보기 버튼)을 표시합니다.</p>
+
+<p>{@link android.app.Activity}
+하위 클래스나 {@link android.app.Fragment} 하위 클래스에서 옵션 메뉴용 항목을 선언할 수 있습니다. 액티비티와 프래그먼트가 모두
+옵션 메뉴용 항목을 선언할 경우, 이들은 UI에서 조합됩니다. 액티비티의 항목이 먼저 나타나고,
+뒤이어 각 프래그먼트의 항목이 나타나며 이때 순서는 각 프래그먼트가 액티비티에 추가된 순서를
+따릅니다. 필요한 경우 이동해야 하는 각 {@code &lt;item&gt;}에서{@code android:orderInCategory} 속성이 포함된
+메뉴 항목을 다시 정렬할 수 있습니다.</p>
+
+<p>액티비티에 대한 옵션 메뉴를 지정하려면 {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}를 재정의합니다(프래그먼트는
+자신만의 {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} 콜백을 제공합니다). 이 메서드에서
+(<a href="#xml">XML에서 정의된</a>) 메뉴 리소스를 콜백에서 제공된 {@link
+android.view.Menu}로 팽창할 수 있습니다. 예:</p>
+
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = {@link android.app.Activity#getMenuInflater()};
+ inflater.inflate(R.menu.game_menu, menu);
+ return true;
+}
+</pre>
+
+<p>또한, {@link android.view.Menu#add(int,int,int,int)
+add()}를 사용하여 메뉴 항목을 추가하고 {@link android.view.Menu#findItem findItem()}로 항목을 검색하여
+{@link android.view.MenuItem} API로 속성을 수정할 수 있습니다.</p>
+
+<p>Android 2.3.x 이하를 대상으로 애플리케이션을 개발했을 경우, 사용자가 처음으로 메뉴를 열었을 때 시스템이 {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}를
+호출합니다. Android 3.0 이상을 대상으로 개발할 경우,
+액티비티를 시작할 때 작업 모음에 항목을 보여주기 위해 시스템이 {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}를
+호출합니다.</p>
+
+
+
+<h3 id="RespondingOptionsMenu">클릭 이벤트 처리</h3>
+
+<p>사용자가 옵션 메뉴에서 항목을 선택하면(작업 모음의 작업 항목 포함),
+시스템이 액티비티의 {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} 메서드를 호출합니다. 이 메서드가 선택한 {@link android.view.MenuItem}을 전달합니다. 항목을 식별하려면
+{@link android.view.MenuItem#getItemId()}을 호출하면 됩니다. 이 메서드는(메뉴 리소스의 {@code android:id} 속성으로 지정되거나
+{@link android.view.Menu#add(int,int,int,int) add()} 메서드에 제공된 정수가 포함된) 메뉴 항목에 대한 고유 ID를 반환합니다
+. 이 ID와
+알려진 메뉴 항목을 일치시켜 적절한 작업을 수행할 수 있습니다. 예:</p>
+
+<pre>
+&#64;Override
+public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.new_game:
+ newGame();
+ return true;
+ case R.id.help:
+ showHelp();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+}
+</pre>
+
+<p>메뉴 항목을 성공적으로 처리하면 {@code true}를 반환합니다. 메뉴 항목을
+처리하지 않으면, {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}의 슈퍼 클래스 구현을 호출해야 합니다(기본
+구현은 '거짓'을 반환합니다).</p>
+
+<p>액티비티에 프래그먼트가 포함되어 있으면, 액티비티에 대해 {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}를 호출하고, 그 다음에는
+하나의 프래그먼트가
+{@code true}를 반환하거나 모든 프래그먼트가 호출될 때까지 (각 프래그먼트가 추가된 순서대로) 각 프래그먼트에 대해 해당 메서드를 호출합니다.</p>
+
+<p class="note"><strong>팁:</strong> Android 3.0에는
+{@code android:onClick} 속성을 사용하여 XML에 있는 메뉴 항목에 대한 온-클릭 동작을 정의하는 기능이 추가됩니다.
+속성 값은 메뉴를 사용하여 액티비티가 정의한 메서드의 이름이어야 합니다. 메서드는
+공개여야 하며 하나의 {@link android.view.MenuItem} 매개변수를 수락해야 합니다. 시스템이 이 메서드를 호출하면
+메서드가 선택한 메뉴 항목을 전달합니다. 자세한 정보와 예시는 <a href="{@docRoot}guide/topics/resources/menu-resource.html">메뉴 리소스</a> 문서를 참조하십시오.</p>
+
+<p class="note"><strong>팁:</strong> 애플리케이션에 여러 액티비티가 포함되어 있고, 그 중 몇몇이 같은 옵션 메뉴를 제공할 경우,
+
+{@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()}와 {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} 메서드를 제외하고 아무것도 구현하지 않는 액티비티를 만드는 것을 고려해보십시오. 그런 다음 이 클래스를 같은 옵션 메뉴를 공유해야 하는 각 액티비티에 대해
+확장하면 됩니다. 이렇게 하면 메뉴 작업을 처리하는 코드 세트 하나를 관리할 수 있고,
+각 하위 클래스가 메뉴 동작을 상속합니다.
+이런 하위 액티비티 중 하나에 메뉴 항목을 추가하려면,
+해당 액티비티에서 {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()}를 재정의하십시오. {@code super.onCreateOptionsMenu(menu)}를 호출하여
+원래 메뉴 항목을 생성하고, {@link
+android.view.Menu#add(int,int,int,int) menu.add()}이 포함된 새로운 메뉴 항목을 추가합니다. 각각의 메뉴 항목에 대한 슈퍼클래스의 동작을
+재정의할 수도 있습니다.</p>
+
+
+<h3 id="ChangingTheMenu">런타임에 메뉴 항목 변경</h3>
+
+<p>시스템이 {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()}를 호출하면, 개발자가 채우는 {@link android.view.Menu}의 인스턴스를 유지하고
+어떤 이유로 메뉴가 무효화되지 않으면{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}를
+호출하지 않습니다. 그러나 {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}는 초기
+메뉴 상태를 생성할 때만 사용하고, 액티비티 수명 주기에서 변경할 때는 사용하지 않습니다.</p>
+
+<p>액티비티 수명 주기에서 발생하는 이벤트에
+기반하여 옵션을 수정하고자 할 경우, 이는
+{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} 메서드에서 할 수 있습니다. 이
+메서드는 현재 존재하는 상태대로 {@link android.view.Menu} 개체를 전달하므로,
+항목을 추가, 삭제, 비활성화하는 등의 수정을 할 수 있습니다 (프래그먼트도 {@link
+android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()} 콜백을 제공합니다).</p>
+
+<p>Android 2.3.x 이하에서는, 사용자가 옵션 메뉴를 열 때마다(<em>메뉴</em>
+버튼 누름) 시스템이{@link
+android.app.Activity#onPrepareOptionsMenu(Menu)
+onPrepareOptionsMenu()}를 호출합니다.</p>
+
+<p>Android 3.0 이상에서는 메뉴 항목이 작업 모음에 표시되어 있을 때마다
+옵션 메뉴는 항상 열려 있는 것으로 간주됩니다. 이벤트가 발생하고 메뉴 업데이트를 수행하고자 하는 경우,
+{@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()}를 호출하여
+시스템이 {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}를 호출하도록 요청해야 합니다.</p>
+
+<p class="note"><strong>참고:</strong>
+현재 초점이 맞춰져 있는 {@link android.view.View}를 기반으로 한
+옵션 메뉴의 항목을 절대로 변경해서는 안 됩니다. 터치 모드에서는(사용자가 트랙볼이나 d-패드를 사용하지 않는 경우),
+보기가 초점을 취할 수 없으므로 옵션 메뉴에 있는 항목을 수정할
+근거로 초점을 사용해서는 결코 안 됩니다. {@link
+android.view.View}의 컨텍스트에 민감한 메뉴를 제공하고자 하는 경우, <a href="#context-menu">컨텍스트 메뉴</a>를 사용하십시오.</p>
+
+
+
+
+<h2 id="context-menu">상황별 메뉴 만들기</h2>
+
+<div class="figure" style="width:420px;margin-top:-1em">
+ <img src="{@docRoot}images/ui/menu-context.png" alt="" />
+ <p class="img-caption"><strong>그림 3.</strong> 부동 컨텍스트 메뉴(왼쪽)
+와 상황별 작업 모음(오른쪽)의 스크린샷입니다.</p>
+</div>
+
+<p>상황별 메뉴는 UI에서 특정 항목이나 컨텍스트 프레임에 영향을 미치는 작업을 제공합니다.
+컨텍스트 메뉴는 어느 보기에나 제공할 수 있지만, {@link
+android.widget.ListView}나 {@link android.widget.GridView}, 사용자가 각 항목에서 직접 작업을 수행하는 기타 보기 컬렉션의
+항목에 가장 자주 사용합니다.</p>
+
+<p>상황별 작업을 제공하는 방법에는 두 가지가 있습니다.</p>
+<ul>
+ <li><a href="#FloatingContextMenu">부동 컨텍스트 메뉴</a>를 사용합니다. 사용자가 컨텍스트 메뉴에 대한 지원을 선언하는 보기를 길게 클릭하면
+(대화와 유사한) 메뉴 항목의 부동 목록이
+나타납니다. 사용자는 한 항목에서 한 번에 하나의 상황별
+작업을 수행할 수 있습니다.</li>
+
+ <li><a href="#CAB">상황별 작업 모드</a>를 사용합니다. 이 모드는 화면 위에 있는 막대에서 선택된 항목에 영향을 미치는 작업 항목이 포함된 <em>상황별 작업 막대</em>를 표시하는
+{@link android.view.ActionMode}의 시스템 구현입니다.
+ 이 모드가 활성 상태이면 사용자는
+여러 개의 항목에서 한 작업을 한꺼번에 수행할 수 있습니다(앱이 이를 허용하는 경우).</li>
+</ul>
+
+<p class="note"><strong>참고:</strong> 상황별 작업 모드는 Android 3.0(API
+레벨 11) 이상에서 이용할 수 있으며, 이용 가능할 때 컨텍스트 작업 표시용으로 기본 설정된 기술입니다.
+ 앱이 3.0 이하의 버전을 지원할 경우 해당 기기에서는
+부동 컨텍스트 메뉴로 돌아가야 합니다.</p>
+
+
+<h3 id="FloatingContextMenu">부동 컨텍스트 메뉴 만들기</h3>
+
+<p>부동 컨텍스트 메뉴를 제공하려면 다음과 같이 합니다.</p>
+<ol>
+ <li>컨텍스트 메뉴가 연관되어야 하는 {@link android.view.View}를 등록합니다. 그러려면
+{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}를 호출하고 여기에
+{@link android.view.View}를 전달하면 됩니다.
+ <p>액티비티가 {@link android.widget.ListView} 또는 {@link android.widget.GridView}를 사용하고
+각 항목이 같은 컨텍스트 메뉴를 제공하게 하고 싶을 경우,
+{@link android.widget.ListView}나 {@link android.widget.GridView}를 {@link
+android.app.Activity#registerForContextMenu(View) registerForContextMenu()}에 전달하여 컨텍스트 메뉴에 모든 항목을 등록합니다.</p>
+</li>
+
+ <li>{@link android.app.Activity}나 {@link android.app.Fragment}에서 {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} 메서드를
+구현합니다.
+ <p>등록된 보기가 롱-클릭 이벤트를 수신하면, 시스템이 {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
+메서드를 호출합니다. 이곳이 바로 메뉴 항목을 정의하는 곳입니다. 주로 메뉴 리소스를 팽창시키는 방법을 씁니다. 예:
+</p>
+<pre>
+&#64;Override
+public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+}
+</pre>
+
+<p>{@link android.view.MenuInflater}를 사용하면 <a href="{@docRoot}guide/topics/resources/menu-resource.html">메뉴 리소스</a>에서 컨텍스트 메뉴를 팽창하게 해줍니다. 콜백 메서드
+매개변수에는 사용자가 선택한 {@link android.view.View}와
+선택한 항목에 대한 추가 정보를 제공하는 {@link android.view.ContextMenu.ContextMenuInfo} 객체가
+포함됩니다. 액티비티에 여러 개의 보기가 있고 이들이 각각 서로 다른 컨텍스트 메뉴를 제공하는 경우,
+이와 같은 매개변수를 사용하여 팽창할 컨텍스트 메뉴가 무엇인지
+판별할 수 있습니다.</p>
+</li>
+
+<li>{@link android.app.Activity#onContextItemSelected(MenuItem)
+onContextItemSelected()}를 구현합니다.
+ <p>사용자가 메뉴 항목을 선택할 경우, 시스템이 이 메서드를 호출하여
+적절한 작업을 수행하게 해줍니다. 예:</p>
+
+<pre>
+&#64;Override
+public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ switch (item.getItemId()) {
+ case R.id.edit:
+ editNote(info.id);
+ return true;
+ case R.id.delete:
+ deleteNote(info.id);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+}
+</pre>
+
+<p>{@link android.view.MenuItem#getItemId()} 메서드는 선택된 메뉴 항목의 ID를 쿼리하고,
+<a href="#xml">
+XML에서 메뉴 정의</a> 섹션에 나타난 바와 같이 {@code
+android:id} 속성을 사용하여 XML의 각 메뉴 항목에 이를 할당해야 합니다.</p>
+
+<p>메뉴 항목을 성공적으로 처리하면 {@code true}를 반환합니다. 메뉴 항목을 처리하지 않는 경우,
+해당 메뉴 항목을 슈퍼클래스 구현에 전달해야 합니다. 액티비티에 프래그먼트가 포함되어 있는 경우
+해당 액티비티가 첫 번째로 이 콜백을 수신합니다. 처리되지 않을 때 슈퍼클래스를 호출하면 시스템이
+이벤트를 각 프래그먼트의 각 콜백 메서드에 전달합니다.
+{@code true} 또는 {@code false}가 반환될 때까지 (각 프래그먼트가 추가된 순서대로) 한 번에 하나씩 전달됩니다 (
+{@link android.app.Activity}와 {@code android.app.Fragment}의 기본 구현이 {@code
+false}를 반환하므로 처리되지 않을 때는 언제나 슈퍼 클래스를 호출해야 합니다).</p>
+</li>
+</ol>
+
+
+<h3 id="CAB">상황별 동작 모드 사용</h3>
+
+<p>상황별 작업 모드는 사용자 상호 작용을 컨텍스트 작업 수행에 집중시키는 {@link android.view.ActionMode}의
+시스템 구현입니다. 사용자가 항목을 선택하여
+이 모드를 활성화하면, <em>상황별 작업 모음</em>이 화면 위에 나타나서
+사용자가 현재 선택된 항목에서 수행할 수 있는 작업을 표시합니다. 이 모드가
+활성화되면 사용자는 여러 항목을 선택하고(개발자가 이를 허용하는 경우), 항목을 선택 해제하고, 액티비티 내에서
+탐색을 계속합니다(개발자가 허용하고자 하는 만큼). 사용자가 모든 항목에서 선택을 해제하고, '뒤로' 버튼을 누르거나
+
+작업 모음 왼쪽의 <em>완료</em> 작업을 누르면 작업 모드가 비활성화되고 상황별 작업 모음이 사라집니다.</p>
+
+<p class="note"><strong>참고:</strong> 상황별 작업 모음이
+반드시 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>과 연관되어 있는 것은 아닙니다. 이들은 서로
+독립적으로 작동합니다. 이는 겉으로 보기에는 상황별 작업 모음이 작업 모음의 위치를 능가하는 것으로
+보이더라도 적용됩니다.</p>
+
+<p>Android 3.0 (API level 11) 이상을 대상으로 개발하는 경우,
+일반적으로 상황별 작업 모드를 사용하여 <a href="#FloatingContextMenu">부동 컨텍스트 메뉴</a>가 아닌 상황별 작업을 표시합니다.</p>
+
+<p>상황별 작업을 제공하는 보기의 경우, 일반적으로 두 이벤트 중 하나(또는 두 가지 모두)에서 상황별 작업 모드를
+호출해야 합니다.</p>
+<ul>
+ <li>사용자가 보기에서 롱-클릭을 수행합니다.</li>
+ <li>사용자가 보기에서 확인란 또는 그와 유사한 UI 구성 요소를 선택합니다.</li>
+</ul>
+
+<p>애플리케이션이 상황별 작업 모드를 호출하고 디자인에 따라 각 작업의 동작을
+정의합니다. 기본적으로 두 가지 디자인이 있습니다.</p>
+<ul>
+ <li>개별적인 임의의 보기에 대한 상황별 작업의 경우.</li>
+ <li>{@link
+android.widget.ListView} 또는 {@link android.widget.GridView}에서 항목 그룹의 일괄 상황별 작업의 경우(사용자가 여러 항목을
+선택하도록 허용하고 모든 항목에서 작업을 수행).</li>
+</ul>
+
+<p>다음 섹션은 각 시나리오에 필요한 설정을 설명합니다.</p>
+
+
+<h4 id="CABforViews">각각의 보기에 대한 상황별 작업 모드의 활성화</h4>
+
+<p>사용자가 특정 보기를 선택했을 때만 상황별 작업 모드를 호출하고자 하는 경우
+다음과 같이 해야 합니다.</p>
+<ol>
+ <li>{@link android.view.ActionMode.Callback} 인터페이스를 구현합니다. 콜백 메서드에서
+상황별 작업 모음의 작업을 지정하고, 작업 항목에 대한 클릭 이벤트에 응답하고, 작업 모드에 대한
+다른 수명 주기 이벤트를 처리합니다.</li>
+ <li>모음을 표시하고자 하는 경우{@link android.app.Activity#startActionMode startActionMode()}를 호출합니다
+(사용자가 보기를 롱-클릭하는 경우).</li>
+</ol>
+
+<p>예:</p>
+
+<ol>
+ <li>{@link android.view.ActionMode.Callback ActionMode.Callback} 인터페이스를 구현합니다.
+<pre>
+private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
+
+ // Called when the action mode is created; startActionMode() was called
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate a menu resource providing context menu items
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+ return true;
+ }
+
+ // Called each time the action mode is shown. Always called after onCreateActionMode, but
+ // may be called multiple times if the mode is invalidated.
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false; // Return false if nothing is done
+ }
+
+ // Called when the user selects a contextual menu item
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_share:
+ shareCurrentItem();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // Called when the user exits the action mode
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
+ }
+};
+</pre>
+
+<p>이벤트 콜백은 <a href="#options-menu">옵션 메뉴</a>의 콜백과 거의 똑같다는 점을 눈여겨 보십시오. 단, 각 콜백은 이벤트와 연결된 {@link
+android.view.ActionMode} 객체를 전달합니다. {@link
+android.view.ActionMode} API를 사용하여
+{@link android.view.ActionMode#setTitle setTitle()}과 {@link
+android.view.ActionMode#setSubtitle setSubtitle()}이 포함된 제목과 하위 제목을 수정하는 등과 같이 CAB를 다양하게 변경합니다(몇 개의
+항목이 선택되었는지 나타낼 때 유용합니다).</p>
+
+<p>또한, 위 샘플은 작업 모드가 소멸될 때 {@code mActionMode} 변수를 null로
+설정한다는 점도 유의하십시오. 다음 단계에서는 액티비티나 프래그먼트의 구성원 변수를 초기화하고 저장하는 방법을
+볼 수 있습니다.</p>
+</li>
+
+ <li>{@link android.app.Activity#startActionMode startActionMode()}를 호출하여
+{@link
+android.view.View}를 롱-클릭했을 경우와 같이 상황에 따라 상황별 작업 모드를 활성화합니다.</p>
+
+<pre>
+someView.setOnLongClickListener(new View.OnLongClickListener() {
+ // Called when the user long-clicks on someView
+ public boolean onLongClick(View view) {
+ if (mActionMode != null) {
+ return false;
+ }
+
+ // Start the CAB using the ActionMode.Callback defined above
+ mActionMode = getActivity().startActionMode(mActionModeCallback);
+ view.setSelected(true);
+ return true;
+ }
+});
+</pre>
+
+<p>{@link android.app.Activity#startActionMode startActionMode()}를 호출하면 시스템이
+생성된 {@link android.view.ActionMode}를 반환합니다. 이것을 구성원 변수에 저장하면
+다른 이벤트에 대한 응답으로 상황별 작업 모음을 변경할 수 있습니다. 위 샘플에서
+{@link android.view.ActionMode}를 사용하여 {@link android.view.ActionMode} 인스턴스가 이미 활성화되었을 경우
+작업 모드를 시작하기 전에 구성원이 null인지 여부를 점검하여
+해당 인스턴스가 재생성되지 않게 합니다.</p>
+</li>
+</ol>
+
+
+
+<h4 id="CABforListView">ListView 또는 GridView에서 일괄 상황별 작업 활성화</h4>
+
+<p>{@link android.widget.ListView} 또는 {@link
+android.widget.GridView}(또는 {@link android.widget.AbsListView}의 또 다른 확장)에 항목 컬렉션이 있고
+사용자가 일괄 작업을 수행하도록 허용하려면 다음과 같이 해야 합니다.</p>
+
+<ul>
+ <li>{@link android.widget.AbsListView.MultiChoiceModeListener} 인터페이스를 구현하고 이를
+{@link android.widget.AbsListView#setMultiChoiceModeListener
+setMultiChoiceModeListener()}가 있는 보기 그룹에 대해 설정합니다. 수신기 콜백 메서드에서 상황별 작업 모음에 대한
+작업을 지정하고, 작업 항목에 대한 클릭 이벤트에 대응하고,
+{@link android.view.ActionMode.Callback} 인터페이스에서 상속한 다른 콜백을 처리할 수 있습니다.</li>
+
+ <li>{@link
+android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL} 인수로 {@link android.widget.AbsListView#setChoiceMode setChoiceMode()}를 호출합니다.</li>
+</ul>
+
+<p>예:</p>
+
+<pre>
+ListView listView = getListView();
+listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
+
+ &#64;Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ // Here you can do something when items are selected/de-selected,
+ // such as update the title in the CAB
+ }
+
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ // Respond to clicks on the actions in the CAB
+ switch (item.getItemId()) {
+ case R.id.menu_delete:
+ deleteSelectedItems();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate the menu for the CAB
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context, menu);
+ return true;
+ }
+
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ // Here you can make any necessary updates to the activity when
+ // the CAB is removed. By default, selected items are deselected/unchecked.
+ }
+
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ // Here you can perform updates to the CAB due to
+ // an {@link android.view.ActionMode#invalidate} request
+ return false;
+ }
+});
+</pre>
+
+<p>완료되었습니다. 이제 사용자가 롱-클릭하여 항목을 선택하면 시스템이 {@link
+android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()}
+메서드를 호출하고 지정된 작업으로 상황별 작업 모음을 표시합니다. 상황별 작업 모음이 표시되는 동안
+사용자가 추가 항목을 선택할 수 있습니다.</p>
+
+<p>상황별 작업이 공통 작업 항목을 제공하는 몇몇 경우,
+확인란이나 그와 비슷한 UI요소를 추가하여 사용자가 항목을 선택할 수 있도록 해주는 것이 좋습니다.
+사용자가 롱-클릭 동작을 발견하지 못할 수도 있기 때문입니다. 사용자가 확인란을 선택하면
+{@link android.widget.AbsListView#setItemChecked setItemChecked()}로
+확인된 상태에 각 목록 항목을 설정하여 상황별 작업 모드를 호출할 수 있습니다.</p>
+
+
+
+
+<h2 id="PopupMenu">팝업 메뉴 만들기</h2>
+
+<div class="figure" style="width:220px">
+<img src="{@docRoot}images/ui/popupmenu.png" alt="" />
+<p><strong>그림 4.</strong> Gmail 앱의 팝업 메뉴는 오른쪽 위에 있는 더보기
+버튼에 고정되어 있습니다.</p>
+</div>
+
+<p>{@link android.widget.PopupMenu}는 {@link android.view.View}에 고정된 모달 메뉴입니다.
+이것은 앵커 보기 아래에 공간이 있으면 아래에, 없으면 보기 위에 나타납니다. 이것은 다음과 같은 상황에 유용합니다.</p>
+<ul>
+ <li>특정 콘텐츠와 <em>관련된</em> 작업에 대한 더보기 스타일 메뉴를 제공합니다(예:
+그림 4의 Gmail 이메일 헤더 등).
+ <p class="note"><strong>참고:</strong> 이것은 컨텍스트 메뉴와는 다릅니다. 컨텍스트 메뉴는
+일반적으로 선택된 콘텐츠에 <em>영향을 미치는</em> 작업입니다. 선택된
+콘텐츠에 영향을 미치는 작업의 경우, <a href="#CAB">상황별 작업 모드</a> 또는 <a href="#FloatingContextMenu">부동 컨텍스트 메뉴</a>를 사용하십시오.</p></li>
+ <li>명령문의 두 번째 부분을 제공합니다(예: "추가"라고 표시된 버튼으로,
+각기 다른 "추가" 옵션이 있는 팝업 메뉴를 발생시킵니다).</li>
+ <li>영구적인 선택이 포함되지 않은 {@link android.widget.Spinner}와 유사한 드롭다운을 제공합니다.
+</li>
+</ul>
+
+
+<p class="note"><strong>참고:</strong> {@link android.widget.PopupMenu}는 API
+레벨 11 이상에서 이용할 수 있습니다.</p>
+
+<p><a href="#xml">XML로 메뉴를 정의</a>하는 경우, 팝업 메뉴를 표시하는 방법은 다음과 같습니다.</p>
+<ol>
+ <li>자신의 생성자로 {@link android.widget.PopupMenu}를 인스턴트화합니다. 생성자는
+현재 애플리케이션 {@link android.content.Context} 및 {@link android.view.View}를
+메뉴를 고정시켜야 하는 곳에 가져갑니다.</li>
+ <li>{@link android.view.MenuInflater}를 사용하여{@link
+android.widget.PopupMenu#getMenu() PopupMenu.getMenu()}가 반환한 {@link
+android.view.Menu} 객체에 메뉴 리소스를 팽창합니다. API 레벨 14 이상에서는 이 대신
+{@link android.widget.PopupMenu#inflate PopupMenu.inflate()}를 사용할 수 있습니다.</li>
+ <li>{@link android.widget.PopupMenu#show() PopupMenu.show()}를 호출합니다.</li>
+</ol>
+
+<p>예를 들어, 다음은 팝업 메뉴를 표시하는 {@link android.R.attr#onClick android:onClick} 속성이
+있는 버튼입니다.</p>
+
+<pre>
+&lt;ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_overflow_holo_dark"
+ android:contentDescription="@string/descr_overflow_button"
+ android:onClick="showPopup" />
+</pre>
+
+<p>그러면 액티비티가 이렇게 팝업 메뉴를 표시할 수 있습니다.</p>
+
+<pre>
+public void showPopup(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.actions, popup.getMenu());
+ popup.show();
+}
+</pre>
+
+<p>API 레벨 14 이상의 경우, {@link
+android.widget.PopupMenu#inflate PopupMenu.inflate()}로 메뉴를 팽창하는 두 개의 줄을 결합시킬 수 있습니다.</p>
+
+<p>사용자가 항목을 선택하거나 메뉴 영역 바깥쪽을 터치하면 이 메뉴는
+무시됩니다. {@link
+android.widget.PopupMenu.OnDismissListener}를 사용하여 무시 이벤트를 수신 대기할 수 있습니다.</p>
+
+<h3 id="PopupEvents">클릭 이벤트 처리</h3>
+
+<p>사용자가 메뉴 항목을 선택할 때 작업을 수행하려면,{@link android.widget.PopupMenu#setOnMenuItemClickListener
+setOnMenuItemclickListener()}를 호출하여
+{@link
+android.widget.PopupMenu.OnMenuItemClickListener} 인터페이스를 구현하고 {@link
+android.widget.PopupMenu}를 등록합니다. 사용자가 항목을 선택하면 시스템이 인터페이스에서 {@link
+android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} 콜백을
+호출합니다.</p>
+
+<p>예:</p>
+
+<pre>
+public void showMenu(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
+
+ // This activity implements OnMenuItemClickListener
+ popup.setOnMenuItemClickListener(this);
+ popup.inflate(R.menu.actions);
+ popup.show();
+}
+
+&#64;Override
+public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.archive:
+ archive(item);
+ return true;
+ case R.id.delete:
+ delete(item);
+ return true;
+ default:
+ return false;
+ }
+}
+</pre>
+
+
+<h2 id="groups">메뉴 그룹 만들기</h2>
+
+<p>메뉴 그룹은 특정한 특성을 공유하는 메뉴 항목의 컬렉션입니다. 그룹으로 다음과 같은 작업을
+할 수 있습니다.</p>
+<ul>
+ <li>{@link android.view.Menu#setGroupVisible(int,boolean)
+setGroupVisible()}로 모든 항목 표시 또는 숨기기</li>
+ <li>{@link android.view.Menu#setGroupEnabled(int,boolean)
+setGroupEnabled()}로 모든 항목 활성화 또는 비활성화</li>
+ <li>{@link
+android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}로 모든 항목이 확인 가능한지 여부 지정</li>
+</ul>
+
+<p>메뉴 리소스의 {@code &lt;group&gt;} 요소 안에 {@code &lt;item&gt;} 요소를 중첩시키거나
+{@link
+android.view.Menu#add(int,int,int,int) add()} 메서드로 그룹 ID를 지정하여 그룹을 생성할 수 있습니다.</p>
+
+<p>다음은 그룹을 포함하는 메뉴 리소스의 예시입니다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/menu_save"
+ android:icon="@drawable/menu_save"
+ android:title="@string/menu_save" /&gt;
+ &lt;!-- menu group --&gt;
+ &lt;group android:id="@+id/group_delete"&gt;
+ &lt;item android:id="@+id/menu_archive"
+ android:title="@string/menu_archive" /&gt;
+ &lt;item android:id="@+id/menu_delete"
+ android:title="@string/menu_delete" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>그룹에 있는 항목은 첫 항목과 같은 레벨에서 표시됩니다. 메뉴 안에 있는 세 가지 항목은 모두
+형제입니다. 그러나 이 그룹에 있는 항목 두 개의 특성을 개발자가 수정할 수 있습니다.
+그룹 ID를 참조하고 위에 나령된 메서드를 사용하면 됩니다. 시스템 또한
+그룹화된 항목은 절대 분리하지 않습니다. 예를 들어, 각 항목에 대해 {@code
+android:showAsAction="ifRoom"}을 선언하면, 두 가지 모두 작업 모음에 나타나거나
+작업 더보기에 나타납니다.</p>
+
+
+<h3 id="checkable">확인 가능한 메뉴 항목 사용</h3>
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/radio_buttons.png" height="333" alt="" />
+ <p class="img-caption"><strong>그림 5.</strong> 확인 가능한
+항목이 있는 하위 메뉴의 스크린샷입니다.</p>
+</div>
+
+<p>메뉴는 옵션을 켜고 끄거나, 독립적 옵션에 대한 확인란으로 사용하거나,
+상호 배타적인 옵션의 그룹에 대한 무선 버튼으로 사용하기 위한 인터페이스로
+유용합니다. 그림 5는 무선 버튼이 있으며 확인 가능한 항목이 포함된 하위 메뉴를
+표시합니다.</p>
+
+<p class="note"><strong>참고:</strong> (옵션 메뉴의) 아이콘 메뉴의 메뉴 항목은
+확인란이나 무선 버튼을 표시할 수 없습니다. 확인 가능한 아이콘 메뉴에서 항목을 만들기로 선택하는 경우,
+상태가 변경될 때마다 아이콘 및/또는 텍스트를 교체하여
+확인된 상태를 수동으로 나타내야 합니다.</p>
+
+<p>{@code &lt;item&gt;} 요소의 {@code
+android:checkable} 속성을 사용하여 개별 메뉴 항목에 대한 확인 가능한 동작을 정의하거나
+{@code &lt;group&gt;} 요소에서 {@code android:checkableBehavior} 속성으로 전체 그룹에 대한 확인 가능한 동작을 사용할 수 있습니다.
+예를 들어, 이 메뉴 그룹의 모든 항목은 무선 버튼으로 확인할 수 있습니다.</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;group android:checkableBehavior="single"&gt;
+ &lt;item android:id="@+id/red"
+ android:title="@string/red" /&gt;
+ &lt;item android:id="@+id/blue"
+ android:title="@string/blue" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>{@code android:checkableBehavior} 속성은 다음 중 하나를 수락합니다.
+<dl>
+ <dt>{@code single}</dt>
+ <dd>그룹의 한 항목만 확인할 수 있습니다(무선 버튼).</dd>
+ <dt>{@code all}</dt>
+ <dd>모든 항목을 확인할 수 있습니다(확인란).</dd>
+ <dt>{@code none}</dt>
+ <dd>확인할 수 있는 항목이 없습니다.</dd>
+</dl>
+
+<p>{@code &lt;item&gt;} 요소의 {@code android:checked} 속성을 이용하여 항목에 기본 확인된 상태를 적용하고
+{@link
+android.view.MenuItem#setChecked(boolean) setChecked()} 메서드로 코드 내에서 이를 변경할 수 있습니다.</p>
+
+<p>확인 가능한 항목이 선택되면, 시스템이 각 항목이 선택된 콜백 메서드를 호출합니다
+(예: {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). 바로 여기에서
+확인란의 상태를 설정해야 합니다. 확인란이나 무선 버튼은 자신의 상태를 자동으로
+변경하지 않기 때문입니다.
+{@link android.view.MenuItem#isChecked()}로 항목의 현재 상태를 (사용자가 이를 선택하기 전 상태 그대로) 쿼리하고 그런 다음
+{@link android.view.MenuItem#setChecked(boolean) setChecked()}로 확인된 상태를 설정할 수 있습니다. 예:</p>
+
+<pre>
+&#64;Override
+public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.vibrate:
+ case R.id.dont_vibrate:
+ if (item.isChecked()) item.setChecked(false);
+ else item.setChecked(true);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+}
+</pre>
+
+<p>이런 방식으로 확인된 상태를 설정하지 않으면, 사용자가 선택했을 때 항목의 가시적 상태(확인란 또는 무선 버튼)가
+변경되지 않습니다.
+ 상태를 설정할 경우, 액티비티는 항목의 확인된 상태를 보존해서
+사용자가 나중에 메뉴를 열었을 때 개발자가 설정한 확인된 상태가
+보이게 합니다.</p>
+
+<p class="note"><strong>참고:</strong>
+확인 가능한 메뉴 항목은 세션별 기준으로만 사용하도록 만들어져 있으며 애플리케이션이 소멸된 후에는
+저장되지 않습니다. 사용자에 대해 저장하고자 하는 애플리케이션 설정이 있으면,
+<a href="{@docRoot}guide/topics/data/data-storage.html#pref">공유 기본 설정</a>으로 해당 데이터를 저장해야 합니다.</p>
+
+
+
+<h2 id="intents">인텐트에 기반한 메뉴 항목 추가</h2>
+
+<p>{@link android.content.Intent}를 이용하여
+액티비티를 시작하는 메뉴 항목을 원할 수도 있습니다(액티비티가 본인의 애플리케이션 안에 있는 것이든 또 다른 애플리케이션에 있는 것이든 무관합니다). 사용하고자 하는 인텐트를 알고
+인텐트를 시작해야 하는 특정 메뉴 항목이 있을 경우,
+항목에 대해 선택된 적절한 콜백 메서드에서 {@link android.app.Activity#startActivity(Intent) startActivity()}가
+포함된 인텐트를 실행합니다(예: {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} 콜백).</p>
+
+<p>그러나 사용자 기기에
+해당 인텐트를 처리하는 애플리케이션이 있는지 모르는 경우, 이를 호출하는 메뉴 항목을 추가하면
+해당 인텐트가 액티비티에 대해 확인되지 못해서 메뉴 항목이 기능하지 못할 수도 있습니다.
+ 이것을 해결하기 위해 Android는 개발자가 동적으로 자신의 메뉴에 메뉴 항목을 추가할 수 있도록 허용합니다.
+이는 Android가 기기에서 개발자의 인텐트를 처리하는 액티비티를 찾을 경우에 해당됩니다.</p>
+
+<p>인텐트를 수락하는 이용 가능한 액티비티에 기반하여 메뉴 항목을 추가하려면 다음과 같이 합니다.</p>
+<ol>
+ <li>
+카테고리 {@link android.content.Intent#CATEGORY_ALTERNATIVE} 및/또는
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, 기타 요구 사항으로 인텐트를 정의합니다.</li>
+ <li>{@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+Menu.addIntentOptions()}을 호출합니다. 그러면 Android가 인텐트를 수행하는 애플리케이션을 검색하고
+이들을 개발자의 메뉴에 추가합니다.</li>
+</ol>
+
+<p>인텐트를 만족하는 애플리케이션이 설치되어 있지 않으면,
+메뉴 항목이 추가되지 않습니다.</p>
+
+<p class="note"><strong>참고:</strong>
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} 를 사용하여 화면에서 현재 선택된
+요소를 처리합니다. 그러므로 이것은 {@link
+android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
+onCreateContextMenu()}에서 메뉴를 생성할 때만 사용해야 합니다.</p>
+
+<p>예:</p>
+
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu){
+ super.onCreateOptionsMenu(menu);
+
+ // Create an Intent that describes the requirements to fulfill, to be included
+ // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
+ Intent intent = new Intent(null, dataUri);
+ intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+
+ // Search and populate the menu with acceptable offering applications.
+ menu.addIntentOptions(
+ R.id.intent_group, // Menu group to which new items will be added
+ 0, // Unique item ID (none)
+ 0, // Order for the items (none)
+ this.getComponentName(), // The current activity name
+ null, // Specific items to place first (none)
+ intent, // Intent created above that describes our requirements
+ 0, // Additional flags to control items (none)
+ null); // Array of MenuItems that correlate to specific items (none)
+
+ return true;
+}</pre>
+
+<p>정의된 인텐트와 일치하는 인텐트 필터를 제공하는 것으로 발견된 각 액티비티에
+인텐트 필터의 <code>android:label</code>를
+메뉴 항목 제목으로, 애플리케이션 아이콘을 메뉴 항목 아이콘으로 사용하여 메뉴 항목을 추가합니다.
+{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()} 메서드는 추가된 메뉴 항목 개수를 반환합니다.</p>
+
+<p class="note"><strong>참고:</strong> {@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()}을 호출할 때 첫 번째 인수에서 지정된 메뉴 그룹이 모든 메뉴 항목을
+재정의합니다.</p>
+
+
+<h3 id="AllowingToAdd">다른 메뉴에 액티비티 추가 허용</h3>
+
+<p>본인의 액티비티의 서비스를 다른 애플리케이션에 제공하여 다른
+애플리케이션의 메뉴에 본인의 애플리케이션이 추가되도록 할 수도 있습니다(위에서 설명한 것과 역할이 반대입니다).</p>
+
+<p>다른 애플리케이션 메뉴에 추가되려면, 인텐트 필터는 평소와 같이
+정의해야 하지만, 인텐트 필터 카테고리에 {@link android.content.Intent#CATEGORY_ALTERNATIVE}
+및/또는{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} 값을
+반드시 포함해야 합니다. 예:</p>
+<pre>
+&lt;intent-filter label="&#64;string/resize_image">
+ ...
+ &lt;category android:name="android.intent.category.ALTERNATIVE" />
+ &lt;category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
+ ...
+&lt;/intent-filter>
+</pre>
+
+<p>인텐트 필터 작성에 관한 자세한 내용은
+<a href="/guide/components/intents-filters.html">인텐트와 인텐트 필터</a> 문서를 참조하십시오.</p>
+
+<p>이 기법을 사용하는 샘플 애플리케이션은
+<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note
+Pad</a> 샘플 코드를 참조하십시오.</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/notifiers/notifications.jd b/docs/html-intl/intl/ko/guide/topics/ui/notifiers/notifications.jd
new file mode 100644
index 000000000000..db55424d8965
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/notifiers/notifications.jd
@@ -0,0 +1,979 @@
+page.title=알림
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Design">디자인 고려 사항</a></li>
+ <li><a href="#CreateNotification">알림 생성</a>
+ <ol>
+ <li><a href="#Required">필수 알림 콘텐츠</a></li>
+ <li><a href="#Optional">선택적 알림 콘텐츠 및 설정</a></li>
+ <li><a href="#Actions">알림 작업</a></li>
+ <li><a href="#Priority">알림 우선 순위</a></li>
+ <li><a href="#SimpleNotification">단순 알림 만들기</a></li>
+ <li><a href="#ApplyStyle">알림에 확장 레이아웃 적용</a></li>
+ <li><a href="#Compatibility">처리 호환성</a></li>
+ </ol>
+ </li>
+ <li><a href="#Managing">알림 관리</a>
+ <ol>
+ <li><a href="#Updating">알림 업데이트</a></li>
+ <li><a href="#Removing">알림 제거</a></li>
+ </ol>
+ </li>
+ <li><a href="#NotificationResponse">액티비티를 시작할 때 탐색 보존</a>
+ <ol>
+ <li><a href="#DirectEntry">정규 액티비티 PendingIntent 설정</a></li>
+ <li><a href="#ExtendedNotification">특수 액티비티 PendingIntent 설정</a></li>
+ </ol>
+ </li>
+ <li><a href="#Progress">알림에서 진행 상태 표시</a>
+ <ol>
+ <li><a href="#FixedProgress">고정 기간 진행 상태 표시기 표시</a></li>
+ <li><a href="#ActivityIndicator">지속적 액티비티 표시기 표시</a></li>
+ </ol>
+ </li>
+ <li><a href="#metadata">알림 메타데이터</a></li>
+ <li><a href="#Heads-up">헤드업 알림</a></li>
+ <li><a href="#lockscreenNotification">잠금 화면 알림</a></li>
+ <ol>
+ <li><a href="#visibility">가시성 설정</a></li>
+ <li><a href="#controllingMedia">잠금 화면에서 미디어 재생 제어</a></li>
+ </ol>
+ <li><a href="#CustomNotification">사용자 지정 알림 레이아웃</a></li>
+</ol>
+
+ <h2>Key 클래스</h2>
+ <ol>
+ <li>{@link android.app.NotificationManager}</li>
+ <li>{@link android.support.v4.app.NotificationCompat}</li>
+ </ol>
+ <h2>비디오</h2>
+ <ol>
+ <li>
+ <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&amp;feature=player_detailpage#t=1672s">
+ 4.1의 알림</a>
+ </li>
+ </ol>
+<h2>참고 항목</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}design/patterns/notifications.html">Android 디자인: 알림</a>
+ </li>
+</ol>
+</div>
+</div>
+<p>
+ 알림은 애플리케이션의 정상 UI 외부에서 사용자에게 표시할 수 있는 메시지입니다.
+시스템에 알림을 실행하라고 명령하면
+처음에 <strong>알림 영역</strong>에서 아이콘으로 나타납니다. 알림 세부 정보를 보려면 사용자는
+<strong>알림 창</strong>을 열어야 합니다. 알림 영역과 알림 창은
+사용자가 언제든 볼 수 있는, 시스템이 제어하는 영역입니다.
+</p>
+<img id="figure1" src="{@docRoot}images/ui/notifications/notification_area.png" height="" alt="" />
+<p class="img-caption">
+ <strong>그림 1.</strong> 알림 영역에 있는 알림입니다.
+</p>
+<img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png" width="280px" alt="" />
+<p class="img-caption">
+ <strong>그림 2.</strong> 알림 창에 있는 알림입니다.
+</p>
+
+<p class="note"><strong>참고:</strong> 따로 언급된 부분을 제외하고 이 가이드는
+버전 4 <a href="{@docRoot}tools/support-library/index.html">지원 라이브러리</a>의 {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} 클래스를
+참조합니다.
+클래스 {@link android.app.Notification.Builder Notification.Builder}는 Android
+3.0(API 레벨 11)에 추가되었습니다.</p>
+
+<h2 id="Design">디자인 고려 사항</h2>
+
+<p>Android 사용자 인터페이스의 중요한 부분인 알림에는 자체적인 디자인 지침이 있습니다.
+Android 5.0(API 레벨 21)부터 도입된 머티어리얼 디자인 변경 사항은
+특히 중요하며, 자세한 정보를 보려면 <a href="{@docRoot}training/material/index.html">재료 디자인</a>
+교육을 검토해야 합니다. 알림과 그 상호작용을 디자인하는 방법을 알아보려면
+<a href="{@docRoot}design/patterns/notifications.html">알림</a> 디자인 가이드를 읽어보십시오.</p>
+
+<h2 id="CreateNotification">알림 생성</h2>
+
+<p>
+{@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} 개체에서 알림에 대한 UI 정보와 작업을 지정합니다.
+알림 자체를 생성하려면
+{@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()}를 호출합니다.
+이는 사양이 포함된 {@link android.app.Notification} 객체를 반환합니다. 알림을 발행하려면
+
+{@link android.app.NotificationManager#notify NotificationManager.notify()}를 호출해서 시스템에 {@link android.app.Notification} 객체를 전달합니다.</p>
+
+<h3 id="Required">필수 알림 콘텐츠</h3>
+<p>
+ {@link android.app.Notification} 객체는 다음을 <em>반드시</em> 포함해야 합니다.
+</p>
+<ul>
+ <li>
+
+{@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()}이 설정한 작은 아이콘
+ </li>
+ <li>
+
+{@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}이 설정한 제목
+ </li>
+ <li>
+
+{@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()}이 설정한 세부 텍스트
+ </li>
+</ul>
+<h3 id="Optional">선택적 알림 콘텐츠 및 설정</h3>
+<p>
+ 다른 모든 알림 설정 및 콘텐츠는 선택 사항입니다. 이들에 관해 자세히 알아보려면
+{@link android.support.v4.app.NotificationCompat.Builder}의 참조 문서를 참조하십시오.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Actions">알림 작업</h3>
+<p>
+ 선택 항목이기는 하지만 알림에 작업을 하나 이상 추가해야 합니다.
+ 작업은 사용자가 알림에서
+애플리케이션의 {@link android.app.Activity}로 바로 갈 수 있게 하고, 여기에서 사용자는 하나 이상의 이벤트를 보거나
+더 많은 작업을 할 수 있습니다.
+</p>
+<p>
+ 하나의 알림은 여러 개의 작업을 제공할 수 있습니다. 사용자가 알림을 클릭했을 때 트리거되는 작업을 항상 정의해야 합니다.
+일반적으로 작업은
+애플리케이션의 {@link android.app.Activity}를 엽니다. 또한, 알람 다시 알림이나 텍스트 메시지에 즉시 답장 등과 같은 추가 작업을 수행하는
+알림 버튼을 추가할 수 있습니다.
+이 기능은 Android 4.1부터 사용할 수 있습니다. 추가 작업 버튼을 사용할 경우,
+앱의 {@link android.app.Activity}에서 해당 기능을 사용할 수 있게 해야 합니다.
+자세한 정보는 <a href="#Compatibility">처리 호환성</a> 섹션을 참조하십시오.
+</p>
+<p>
+ {@link android.app.Notification}에서 작업 자체는
+애플리케이션에서 {@link android.app.Activity}를 시작하는
+{@link android.content.Intent}가 포함된
+{@link android.app.PendingIntent}가 정의합니다.
+{@link android.app.PendingIntent}를 동작과 연관시키려면
+{@link android.support.v4.app.NotificationCompat.Builder}의 적절한 메서드를 호출합니다. 예를 들어,
+사용자가 알림 창의 알림 텍스트를 클릭했을 때 {@link android.app.Activity}를 시작하려면,
+
+{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}를 호출하여 {@link android.app.PendingIntent}를 추가합니다.
+</p>
+<p>
+ 사용자가 알림을 클릭했을 때 {@link android.app.Activity}를 시작하는 동작이 가장 보편적인 작업
+시나리오입니다. 또한, 사용자가 알림을 무시했을 때 {@link android.app.Activity}를
+시작할 수도 있습니다. Android 4.1 이후부터는
+{@link android.app.Activity}를 작업 버튼에서 시작할 수 있습니다. 자세한 내용을 알아보려면
+{@link android.support.v4.app.NotificationCompat.Builder} 참조 가이드를 읽어보십시오.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Priority">알림 우선 순위</h3>
+<p>
+ 원한다면, 알림에 우선 순위를 설정할 수 있습니다. 우선 순위는
+기기 UI에 알림 표시 방식을 암시하는 역할을 합니다.
+ 알림 우선 순위를 설정하려면, {@link
+android.support.v4.app.NotificationCompat.Builder#setPriority(int)
+NotificationCompat.Builder.setPriority()}를 호출하고 {@link
+android.support.v4.app.NotificationCompat} 우선 순위 상수 중 하나에 전달합니다.
+우선 순위 수준은 {@link
+android.support.v4.app.NotificationCompat#PRIORITY_MIN}(-2)에서 {@link
+android.support.v4.app.NotificationCompat#PRIORITY_MAX}(2)까지 다섯 개가 있습니다. 별도의 설정이 없을 경우,
+우선 순위 기본값은 {@link
+android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT}(0)으로 설정됩니다.
+</p>
+<p> 적절한 우선 순위 수준 설정에 관한 정보는 <a href="{@docRoot}design/patterns/notifications.html">알림</a> 디자인 가이드에서 "알림 우선 순위 올바르게 설정하고 관리하기"를
+참조하십시오.
+
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="SimpleNotification">단순 알림 만들기</h3>
+<p>
+ 다음 조각은 사용자가 알림을 클릭하면 알리는
+액티비티를 지정하는 단순한 알림을 나타냅니다. 이 코드는
+{@link android.support.v4.app.TaskStackBuilder} 객체를 생성하고 이를 사용하여
+해당 작업의 {@link android.app.PendingIntent}를 생성합니다. 이 패턴은
+<a href="#NotificationResponse">
+액티비티를 시작할 때 탐색 보존</a> 섹션에서 자세히 설명합니다.
+</p>
+<pre>
+NotificationCompat.Builder mBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.notification_icon)
+ .setContentTitle("My notification")
+ .setContentText("Hello World!");
+// Creates an explicit intent for an Activity in your app
+Intent resultIntent = new Intent(this, ResultActivity.class);
+
+// The stack builder object will contain an artificial back stack for the
+// started Activity.
+// This ensures that navigating backward from the Activity leads out of
+// your application to the Home screen.
+TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+// Adds the back stack for the Intent (but not the Intent itself)
+stackBuilder.addParentStack(ResultActivity.class);
+// Adds the Intent that starts the Activity to the top of the stack
+stackBuilder.addNextIntent(resultIntent);
+PendingIntent resultPendingIntent =
+ stackBuilder.getPendingIntent(
+ 0,
+ PendingIntent.FLAG_UPDATE_CURRENT
+ );
+mBuilder.setContentIntent(resultPendingIntent);
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// mId allows you to update the notification later on.
+mNotificationManager.notify(mId, mBuilder.build());
+</pre>
+<p>완료되었습니다. 이제 사용자에게 알림이 전달되었습니다.</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ApplyStyle">알림에 확장 레이아웃 적용</h3>
+<p>
+ 확장된 보기에 알림을 나타나게 하려면,
+먼저 원하는 일반 보기 옵션으로 {@link android.support.v4.app.NotificationCompat.Builder} 객체를
+생성합니다. 다음에는 확장된 레이아웃 객체의 인수로 {@link android.support.v4.app.NotificationCompat.Builder#setStyle
+Builder.setStyle()}을 호출합니다.
+</p>
+<p>
+ 확장 알림은 Android 4.1 이전 플랫폼에서 사용할 수 없다는 것을 명심하십시오.
+Android 4.1 이하 플랫폼에서 알림을 처리하는 방법은
+<a href="#Compatibility">처리 호환성</a> 섹션을 참조하십시오.
+</p>
+<p>
+ 예를 들어, 다음 코드 조각은
+이전 조각에서 생성된 알림을 변경하여 확장 레이아웃을 사용하는 방법을 나타냅니다.
+</p>
+<pre>
+NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.notification_icon)
+ .setContentTitle("Event tracker")
+ .setContentText("Events received")
+NotificationCompat.InboxStyle inboxStyle =
+ new NotificationCompat.InboxStyle();
+String[] events = new String[6];
+// Sets a title for the Inbox in expanded layout
+inboxStyle.setBigContentTitle("Event tracker details:");
+...
+// Moves events into the expanded layout
+for (int i=0; i &lt; events.length; i++) {
+
+ inboxStyle.addLine(events[i]);
+}
+// Moves the expanded layout object into the notification object.
+mBuilder.setStyle(inBoxStyle);
+...
+// Issue the notification here.
+</pre>
+
+<h3 id="Compatibility">처리 호환성</h3>
+
+<p>
+
+알림 기능을 설정하는 메서드가
+지원 라이브러리 클래스 {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}에 있더라도 모든 알림 기능을 특정 버전에서 사용할 수 있는 것은 아닙니다.
+ 예를 들어, 확장 알림에 따라 달라지는 작업 버튼은 Android
+4.1 이상에만 나타납니다. 확장 알림 자체를
+Android 4.1 이상에서만 이용할 수 있기 때문입니다.
+</p>
+<p>
+ 최상의 호환성을 보장하기 위해
+알림은 {@link android.support.v4.app.NotificationCompat NotificationCompat}와 하위 클래스,
+특히 {@link android.support.v4.app.NotificationCompat.Builder
+NotificationCompat.Builder}를 이용해서 알림을 생성합니다. 또한, 알림을 구현할 때 이 절차를 따릅니다.
+</p>
+<ol>
+ <li>
+ 사용하는 버전에 관계없이
+모든 사용자에게 모든 알림 기능을 제공합니다. 이를 위해서
+앱의 {@link android.app.Activity}에서 모든 기능을 이용할 수 있는지 검증합니다. 그러려면
+새로운 {@link android.app.Activity}를 추가해야 할 수도 있습니다.
+ <p>
+ 예를 들어,
+여러분이{@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()}을 사용하여
+미디어 재생을 중지하고 시작하는 제어를 제공하고 싶다면
+먼저 앱의 {@link android.app.Activity}에 이 제어를 구현합니다.
+ </p>
+ </li>
+ <li>
+ 사용자가 알림을 클릭하면 알림을 시작시키는 방식으로 모든 사용자에게 {@link android.app.Activity}에서 알림 기능을
+사용할 수 있게 합니다. 이를 위해,
+
+{@link android.app.Activity}를 위한 {@link android.app.PendingIntent}를 생성합니다.
+{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+setContentIntent()}를 호출하여 알림에 {@link android.app.PendingIntent}를 추가합니다.
+ </li>
+ <li>
+ 이제 알림에서 사용하고자 하는 확장 알림 기능을 추가합니다. 또한, 사용자가 알림을 클릭하면 시작되는
+{@link android.app.Activity}에서 개발자가 추가한 모든 기능을
+사용할 수 있어야 합니다.
+ </li>
+</ol>
+
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="Managing">알림 관리</h2>
+<p>
+ 같은 유형의 이벤트에서 알림을 여러 번 발행해야 할 경우,
+완전히 새로운 알림을 만드는 것은 삼가야 합니다. 대신, 일부 값을 변경하거나 추가하거나, 두 가지 조치를 모두 취하여
+이전 알림을 업데이트하는 것이 좋습니다.
+</p>
+<p>
+ 예를 들어, Gmail은 읽지 않은 메시지 개수를 올리고 각 이메일의 요약을 알림에 추가하여
+새 이메일 도착을 알립니다. 이것을 일명
+알림을 "쌓는다"고 하며, 이는
+<a href="{@docRoot}design/patterns/notifications.html">알림</a> 디자인 가이드에 자세히 설명되어 있습니다.
+</p>
+<p class="note">
+ <strong>참고:</strong> 이 Gmail 기능에는 "받은편지함" 확장 레이아웃이 필요한데,
+이것은 Android 4.1부터 이용할 수 있는 확장 알림 기능의 일부입니다.
+</p>
+<p>
+ 다음 섹션은 알림 업데이트 방법과 삭제 방법을 설명합니다.
+</p>
+<h3 id="Updating">알림 업데이트</h3>
+<p>
+ 알림이 업데이트되도록 설정하려면,
+{@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}를 호출하여 알림 ID와 함께 발행합니다.
+ 알림을 발행한 후에 업데이트하려면,
+{@link android.support.v4.app.NotificationCompat.Builder} 객체를 업데이트하거나 생성하고,
+{@link android.app.Notification} 객체를 구축하고,
+이전에 사용한 것과 같은 ID로 {@link android.app.Notification}을 발행합니다. 이전 알림이
+여전히 표시되는 경우, 시스템은
+{@link android.app.Notification} 객체의 콘텐츠에서 알림을 업데이트합니다. 이전 알림을 무시할 경우,
+대신 새로운 알림이 생성됩니다.
+</p>
+<p>
+ 다음 코드 조각은 발생한 이벤트 개수를 반영하여
+업데이트된 알림을 나타낸 것입니다. 이것은 알림을 쌓아 요약을 표시합니다.
+</p>
+<pre>
+mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// Sets an ID for the notification, so it can be updated
+int notifyID = 1;
+mNotifyBuilder = new NotificationCompat.Builder(this)
+ .setContentTitle("New Message")
+ .setContentText("You've received new messages.")
+ .setSmallIcon(R.drawable.ic_notify_status)
+numMessages = 0;
+// Start of a loop that processes data and then notifies the user
+...
+ mNotifyBuilder.setContentText(currentText)
+ .setNumber(++numMessages);
+ // Because the ID remains unchanged, the existing notification is
+ // updated.
+ mNotificationManager.notify(
+ notifyID,
+ mNotifyBuilder.build());
+...
+</pre>
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Removing">알림 제거</h3>
+<p>
+ 알림은 다음 중 하나가 발생할 때까지 계속 표시된 상태로 유지됩니다.
+</p>
+<ul>
+ <li>
+ 사용자가 개별적으로 삭제하거나 "모두 삭제"를 사용하여 알림을 무시합니다(
+알림을 지울 수 있는 경우).
+ </li>
+ <li>
+ 사용자가 알림을 클릭하고, 알림을 생성했을 때
+{@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} 을 호출했을 경우입니다.
+
+ </li>
+ <li>
+ 특정 알림 ID에 대해 {@link android.app.NotificationManager#cancel(int) cancel()}을 호출합니다.
+이 메서드도 현재 진행 중인 알림을 삭제합니다.
+ </li>
+ <li>
+ {@link android.app.NotificationManager#cancelAll() cancelAll()}을 호출합니다.
+이것은 이전에 발행한 알림을 모두 제거합니다.
+ </li>
+</ul>
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="NotificationResponse">액티비티를 시작할 때 탐색 보존</h2>
+<p>
+ 알림에서 {@link android.app.Activity}를 시작할 때는 사용자의 예상 탐색 경험을
+보존해야 합니다. <i>'뒤로'를 클릭하면</i> 사용자를 애플리케이션의 정상 작업 흐름을 거쳐 메인 스크린으로 보내고,
+ <i>'최근'을 클릭하면</i>
+{@link android.app.Activity}를 별개의 작업으로 표시합니다. 탐색 경험을 보존하려면
+새 작업에서 {@link android.app.Activity}를 시작해야 합니다. 새로운 작업을 부여하기 위한
+{@link android.app.PendingIntent} 설정 방법은 시작하는
+{@link android.app.Activity}의 성격에 따라 달라집니다. 여기에는 두 가지 일반적인 상황이 있습니다.
+</p>
+<dl>
+ <dt>
+ 정규 액티비티
+ </dt>
+ <dd>
+ 애플리케이션의 정상적 작업 흐름의 일부인 {@link android.app.Activity}를
+시작합니다. 이 상황에서 {@link android.app.PendingIntent}를 설정하여
+새 작업을 시작하고 애플리케이션의
+정상적인 <i>'뒤로' </i>동작을 재현하는 백 스택으로 {@link android.app.PendingIntent}를 제공합니다.
+ <p>
+ Gmail 앱에서 보낸 알림이 이것을 잘 보여줍니다. 하나의 이메일 메시지에 대한
+알림을 클릭하면 메시지 자체를 보게 됩니다. <b>뒤로</b>를 터치하면
+알림에서 들어간 것이 아니라 메인 스크린에서
+Gmail에 들어간 것처럼 Gmail을 통해 메인 스크린으로 돌아갑니다.
+ </p>
+ <p>
+ 이것은 알림을 터치하기만 하면 어느 애플리케이션에 있든 관계 없이 발생하는
+일입니다. 예를 들어, Gmail에서 메시지를 작성하다가
+한 이메일에 대한 알림을 클릭하면 해당 이메일로 바로 이동합니다. <i>뒤로</i>
+를 터치하면
+작성 중인 메시지가 아니라 받은편지함과 메인 스크린으로 돌아갑니다.
+ </p>
+ </dd>
+ <dt>
+ 특수 액티비티
+ </dt>
+ <dd>
+ {@link android.app.Activity}가 알림에서 시작될 경우 사용자에게는 이것만 보입니다.
+ {@link android.app.Activity}는 알림 자체에서 표시하기 어려운 정보를 제공하므로
+어떤 면에서는 알림을 확장하는 셈입니다. 이 상황에서는,
+{@link android.app.PendingIntent}를 설정하고 새로운 작업에서 시작합니다.
+시작된 {@link android.app.Activity}는
+애플리케이션 액티비티 흐름의 일부가 아니므로 백 스택을 생성하지 않아도 됩니다. <i>뒤로</i>를 클릭하면 사용자는 여전히
+메인 스크린으로 돌아갑니다.
+ </dd>
+</dl>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="DirectEntry">정규 액티비티 PendingIntent 설정</h3>
+<p>
+ 직접 진입
+{@link android.app.Activity}를 시작하는 {@link android.app.PendingIntent}를 설정하려면 다음과 같은 단계를 따르십시오.
+</p>
+<ol>
+ <li>
+ 매니페스트에서 애플리케이션의 {@link android.app.Activity} 계층을 정의합니다.
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+ Android 4.0.3 이전에 대한 지원을 추가합니다. 이렇게 하려면
+
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+요소를
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>의 하위 요소로 추가하여 개발자가 시작하는 {@link android.app.Activity}의 상위 요소를 지정합니다.
+ <p>
+ 이 요소의 경우,
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>를 설정합니다.
+ <code>&lt;parent_activity_name&gt;</code>가
+상위 요소 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+에 대한
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>의 값인
+
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="&lt;parent_activity_name&gt;"</code>
+를 시작합니다. 다음 XML을 예시로 참조하십시오.
+ </p>
+ </li>
+ <li>
+ Android 4.1 이후에 대한 지원도 추가합니다. 이렇게 하려면 개발자가 시작하는 {@link android.app.Activity}의
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ 요소에
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code>
+속성을 추가합니다.
+ </li>
+ </ol>
+ <p>
+ 최종 XML은 이런 모습을 띠는 것이 정상입니다.
+ </p>
+<pre>
+&lt;activity
+ android:name=".MainActivity"
+ android:label="&#64;string/app_name" &gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+&lt;activity
+ android:name=".ResultActivity"
+ android:parentActivityName=".MainActivity"&gt;
+ &lt;meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".MainActivity"/&gt;
+&lt;/activity&gt;
+</pre>
+ </li>
+ <li>
+ {@link android.app.Activity}를 시작하는 {@link android.content.Intent}에 기초하여
+백 스택을 생성합니다.
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+ {@link android.content.Intent}를 생성하여 {@link android.app.Activity}를 생성합니다.
+ </li>
+ <li>
+ {@link android.app.TaskStackBuilder#create
+TaskStackBuilder.create()}를 호출하여 스택 빌더를 생성합니다.
+ </li>
+ <li>
+
+{@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}을 호출하여 스택 빌더를 백 스택에 추가합니다.
+ 매니페스트에서 정의한 계층의 각 {@link android.app.Activity}의 경우,
+백 스택에
+{@link android.app.Activity}를 시작하는 {@link android.content.Intent} 객체가 포함됩니다. 이 메서드는 새로운 작업에서
+스택을 시작하는 플래그도 추가합니다.
+ <p class="note">
+ <strong>참고:</strong>
+{@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}에 대한 인수가
+시작된 {@link android.app.Activity}의 참조이기는 하지만, 이 메서드 호출은
+
+{@link android.app.Activity}를 시작하는 {@link android.content.Intent}를 추가하지 않습니다. 대신, 그 부분은 다음 단계에서 해결합니다.
+ </p>
+ </li>
+ <li>
+
+{@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}를 호출하여 {@link android.app.Activity}를 시작하는 {@link android.content.Intent}를
+추가합니다.
+ 첫 번째 단계에서 생성한 {@link android.content.Intent}를
+
+{@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}에 대한 인수로 전달합니다.
+ </li>
+ <li>
+ 필요할 경우
+{@link android.support.v4.app.TaskStackBuilder#editIntentAt
+TaskStackBuilder.editIntentAt()}을 호출하여 스택에서{@link android.content.Intent} 객체에 대한 인수를 추가합니다. 이것은 사용자가
+
+<i>'뒤로'</i>를 사용하여 탐색할 때 대상{@link android.app.Activity}가 의미 있는 데이터를 표시하도록 보장하기 위해 때때로 필요한 절차입니다.
+ </li>
+ <li>
+ 이 백 스택에 대한 {@link android.app.PendingIntent}를 가져옵니다. 이때
+{@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()}를 호출하는 방법을 씁니다.
+ 그러면 이 {@link android.app.PendingIntent}를
+{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+setContentIntent()}에 대한 인수로 사용할 수 있습니다.
+ </li>
+ </ol>
+ </li>
+</ol>
+<p>
+ 다음 코드 조각은 이 과정을 나타낸 것입니다.
+</p>
+<pre>
+...
+Intent resultIntent = new Intent(this, ResultActivity.class);
+TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+// Adds the back stack
+stackBuilder.addParentStack(ResultActivity.class);
+// Adds the Intent to the top of the stack
+stackBuilder.addNextIntent(resultIntent);
+// Gets a PendingIntent containing the entire back stack
+PendingIntent resultPendingIntent =
+ stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
+...
+NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+builder.setContentIntent(resultPendingIntent);
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+mNotificationManager.notify(id, builder.build());
+</pre>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ExtendedNotification">특수 액티비티 PendingIntent 설정</h3>
+<p>
+ 다음 섹션에서는 특수 액티비티
+{@link android.app.PendingIntent}를 설정하는 법을 설명합니다.
+</p>
+<p>
+ 특수 {@link android.app.Activity}에는 백 스택이 필요하지 않습니다. 따라서 매니페스트에서 이것의
+{@link android.app.Activity} 계층을 정의하지 않아도 되고,
+백 스택을 구축하기 위해
+{@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}을
+호출하지 않아도 됩니다. 대신 매니페스트를 사용하여 {@link android.app.Activity} 작업 옵션을 설정하고,
+{@link android.app.PendingIntent}를 생성하십시오. 이때
+{@link android.app.PendingIntent#getActivity getActivity()}를 호출하는 방법을 씁니다.
+</p>
+<ol>
+ <li>
+ 매니페스트에서 다음 속성을 {@link android.app.Activity}에 대한
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+요소에 추가합니다.
+ <dl>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code>
+ </dt>
+ <dd>
+ 액티비티의 완전히 정규화된 클래스 이름입니다.
+ </dd>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code>
+ </dt>
+ <dd>
+ 이것은 개발자가 코드에서 설정하는
+{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} 플래그와 더불어
+이 {@link android.app.Activity}가
+애플리케이션의 기본 작업으로 들어가지 않게 보장합니다. 애플리케이션의 기본 유사성을
+가지고 있는 기존 작업은 모두 영향을 받지 않습니다.
+ </dd>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code>
+ </dt>
+ <dd>
+ 새 작업을 <i>최근</i>에서 배제하여 사용자가 우연히
+이곳으로 다시 이동하지 못하게 합니다.
+ </dd>
+ </dl>
+ <p>
+ 이 조각은 해당 요소를 나타낸 것입니다.
+ </p>
+<pre>
+&lt;activity
+ android:name=".ResultActivity"
+...
+ android:launchMode="singleTask"
+ android:taskAffinity=""
+ android:excludeFromRecents="true"&gt;
+&lt;/activity&gt;
+...
+</pre>
+ </li>
+ <li>
+ 알림을 구축 및 발행합니다.
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+
+{@link android.app.Activity}를 시작하는 {@link android.content.Intent}를 생성합니다.
+ </li>
+ <li>
+ {@link android.app.Activity}가 새로운, 빈 작업에서 시작되도록 설정합니다. 이때
+{@link android.content.Intent#setFlags setFlags()}를
+{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
+ 및
+{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK} 플래그와 함께 호출하면 됩니다.
+ </li>
+ <li>
+ {@link android.content.Intent}에 필요한 다른 모든 옵션을 설정합니다.
+ </li>
+ <li>
+ {@link android.app.PendingIntent}를 {@link android.content.Intent}로부터
+생성합니다. 이때 {@link android.app.PendingIntent#getActivity getActivity()}를 호출하면 됩니다.
+ 그러면 이 {@link android.app.PendingIntent}를
+{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+setContentIntent()}에 대한 인수로 사용할 수 있습니다.
+ </li>
+ </ol>
+ <p>
+ 다음 코드 조각은 이 과정을 나타낸 것입니다.
+ </p>
+<pre>
+// Instantiate a Builder object.
+NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+// Creates an Intent for the Activity
+Intent notifyIntent =
+ new Intent(this, ResultActivity.class);
+// Sets the Activity to start in a new, empty task
+notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+// Creates the PendingIntent
+PendingIntent notifyPendingIntent =
+ PendingIntent.getActivity(
+ this,
+ 0,
+ notifyIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT
+);
+
+// Puts the PendingIntent into the notification builder
+builder.setContentIntent(notifyPendingIntent);
+// Notifications are issued by sending them to the
+// NotificationManager system service.
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// Builds an anonymous Notification object from the builder, and
+// passes it to the NotificationManager
+mNotificationManager.notify(id, builder.build());
+</pre>
+ </li>
+</ol>
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="Progress">알림에서 진행 상태 표시</h2>
+<p>
+ 알림에는 사용자에게 진행 중인 작업의 상태를 보여주는
+애니메이션 진행 표시기를 포함할 수 있습니다. 작업이 얼마나 걸릴지, 주어진 시점에 어느 정도 완료되었는지를 추정할 수 있는 경우
+표시기의 "확정적" 형태(진행률 표시줄)를
+사용하십시오. 작업의 길이를 추정할 수 없으면, 표시기의
+"비확정적" 형태(액티비티 표시기)를 사용하십시오.
+</p>
+<p>
+ 진행 상태 표시기는
+{@link android.widget.ProgressBar} 클래스의 플랫폼 구현으로 표시됩니다.
+</p>
+<p>
+ Android 4.0부터 시작되는 플랫폼에서 진행 상태 표시기를 사용하려면,
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}를 호출하십시오. 이전
+버전의 경우, 개발자 나름의 사용자 지정 알림 레이아웃을 생성해야 하며 여기에
+{@link android.widget.ProgressBar} 보기가 포함되어 있어야 합니다.
+</p>
+<p>
+ 다음 섹션은
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}를 사용하여 알림의 진행 상태를 표시하는 법을 설명합니다.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="FixedProgress">고정 기간 진행 상태 표시기 표시</h3>
+<p>
+ 확정적인 진행률 표시줄을 표시하려면
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress
+setProgress(max, progress, false)}를 호출하여 표시줄을 알림에 추가하고, 그 다음에 알림을 발행합니다. 작업이 진행되는 동안
+<code>progress</code>를 증가시키고 알림을 업데이트합니다. 작업이 끝날 무렵
+<code>progress</code>가 <code>max</code>와 같아야 합니다.
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}를 호출하는 보편적인 방법은
+<code>max</code>를 100에 설정하고 작업에 대한 "완료 비율" 값에 따라 <code>progress</code>를
+증가시키는 것입니다.
+</p>
+<p>
+ 작업이 완료되면 진행률 표시줄이 표시되는 상태로 둘 수도 있고, 제거할 수도 있습니다. 어느 경우를 택하더라도
+알림 텍스트를 업데이트하여 작업이 완료되었다고 표시하는 것을 잊지 마십시오.
+ 진행률 표시줄을 제거하려면,
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress
+setProgress(0, 0, false)}를 호출합니다. 예:
+</p>
+<pre>
+...
+mNotifyManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+mBuilder = new NotificationCompat.Builder(this);
+mBuilder.setContentTitle("Picture Download")
+ .setContentText("Download in progress")
+ .setSmallIcon(R.drawable.ic_notification);
+// Start a lengthy operation in a background thread
+new Thread(
+ new Runnable() {
+ &#64;Override
+ public void run() {
+ int incr;
+ // Do the "lengthy" operation 20 times
+ for (incr = 0; incr &lt;= 100; incr+=5) {
+ // Sets the progress indicator to a max value, the
+ // current completion percentage, and "determinate"
+ // state
+ mBuilder.setProgress(100, incr, false);
+ // Displays the progress bar for the first time.
+ mNotifyManager.notify(0, mBuilder.build());
+ // Sleeps the thread, simulating an operation
+ // that takes time
+ try {
+ // Sleep for 5 seconds
+ Thread.sleep(5*1000);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "sleep failure");
+ }
+ }
+ // When the loop is finished, updates the notification
+ mBuilder.setContentText("Download complete")
+ // Removes the progress bar
+ .setProgress(0,0,false);
+ mNotifyManager.notify(ID, mBuilder.build());
+ }
+ }
+// Starts the thread by calling the run() method in its Runnable
+).start();
+</pre>
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ActivityIndicator">지속적 액티비티 표시기 표시</h3>
+<p>
+ 비확정적 액티비티 표시기를 표시하려면,
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)}으로 알림에 표시기를 추가하고(처음의 인수 두 개는 무시합니다)
+, 알림을 발행합니다. 그 결과로
+진행률 표시줄과 같은 스타일의 표시기가 나타납니다. 다만 이것은 애니메이션이 계속 진행 중입니다.
+</p>
+<p>
+ 작업을 시작할 때 알림을 발행합니다. 애니메이션은
+알림을 수정할 때까지 실행됩니다. 작업이 완료되면,
+{@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)}를 호출하고
+알림을 업데이트하여 액티비티 표시기를 제거합니다.
+ 이 작업은 항상 해야 합니다. 하지 않으면, 작업이 완료되더라도 애니메이션이 계속 실행됩니다. 또한,
+알림 텍스트를 변경하여 작업이 완료되었음을 나타내는 것을 잊지 마십시오.
+</p>
+<p>
+ 액티비티 표시기의 작동 원리를 알아보려면 이어지는 코드 조각을 참조하십시오. 다음 줄을 찾을 수 있습니다.
+</p>
+<pre>
+// Sets the progress indicator to a max value, the current completion
+// percentage, and "determinate" state
+mBuilder.setProgress(100, incr, false);
+// Issues the notification
+mNotifyManager.notify(0, mBuilder.build());
+</pre>
+<p>
+ 찾은 줄을 다음 줄로 교체하십시오.
+</p>
+<pre>
+ // Sets an activity indicator for an operation of indeterminate length
+mBuilder.setProgress(0, 0, true);
+// Issues the notification
+mNotifyManager.notify(0, mBuilder.build());
+</pre>
+
+<h2 id="metadata">알림 메타데이터</h2>
+
+<p>알림은
+다음 {@link android.support.v4.app.NotificationCompat.Builder} 메서드로 할당된 메타데이터에 따라 정렬할 수 있습니다.</p>
+
+<ul>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()}는
+기기가 우선 순위 모드일 때 앱 알림을 처리하는 방법을 시스템에 전달합니다
+(예를 들어, 알림이 수신 전화나 채팅 메시지, 알람 등을 나타낼 경우).</li>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()}는
+우선 순위 필드가 포함된 알림을 {@code PRIORITY_MAX} 또는 {@code PRIORITY_HIGH}로 설정하고,
+알림에 소리나 진동이 포함되어 있을 경우 작은 부동 창에 나타나게 합니다.</li>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()}을
+사용하면 알림에 사람 목록을 추가할 수 있게 해줍니다. 개발자의 앱은 이 신호를 사용하여
+시스템에 지정된 사람들로부터 받은 알림을 함께 그룹화해야 한다고 알리거나, 이런 사람들로부터 받은 알림을
+더욱 중요한 것으로 순위를 높일 수 있습니다.</li>
+</ul>
+
+<div class="figure" style="width:230px">
+ <img src="{@docRoot}images/ui/notifications/heads-up.png" alt="" width="" height="" id="figure3" />
+ <p class="img-caption">
+ <strong>그림 3.</strong> 헤드업 알림을 표시하고 있는 전체 화면 액티비티
+ </p>
+</div>
+
+<h2 id="Heads-up">헤드업 알림</h2>
+
+<p>Android 5.0(API 레벨 21)에서는 알림을 작은 부동 창에 나타낼 수 있습니다
+(다른 말로 <em>헤드업 알림</em>이라고 부릅니다). 이것은 기기가 활성 상태일 때(즉,
+기기가 잠금 해제 상태이며 화면에 켜져 있는 경우) 해당됩니다. 이와 같은 알림은
+외견상 일반적인 알림의 소형 형태와 비슷해 보이지만,
+해드업 알림에서는 작업 버튼도 표시한다는 점이 다릅니다. 사용자는 현재 앱을 떠나지 않고도
+헤드업 알림에 조치를 취하거나 이를 무시할 수 있습니다.</p>
+
+<p>헤드업 알림을 트리거할 수 있는 조건의 예시를 몇 가지 소개하면 다음과 같습니다.</p>
+
+<ul>
+ <li>사용자 액티비티가 전체 화면 모드이거나(앱이
+{@link android.app.Notification#fullScreenIntent}를 사용할 경우)</li>
+ <li>알림의 우선 순위가 높고
+벨소리나 진동을 사용할 경우</li>
+</ul>
+
+<h2 id="lockscreenNotification">잠금 화면 알림</h2>
+
+<p>Android 5.0 (API 레벨 21) 릴리스부터 알림이 잠금 화면에도
+나타날 수 있게 되었습니다. 앱은 이 기능을 사용하면 미디어 재생 제어와 다른 보편적인 작업을
+제공할 수 있습니다. 사용자는 설정을 통해 잠금 화면에 알림 표시 여부를 선택할 수 있고,
+개발자는 앱의 알림이 잠금 화면에 표시될지 여부를 지정할 수 있습니다.</p>
+
+<h3 id="visibility">가시성 설정</h3>
+
+<p>보안 잠금 화면에 알림이 얼마나 상세하게 표시될 것인지 그 수준을 앱이 제어할 수
+있습니다. {@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()}를 호출하고
+다음 값 중 하나를 지정합니다.</p>
+
+<ul>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC}은
+알림의 전체 콘텐츠를 표시합니다.</li>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET}은
+이 알림의 어떤 부분도 화면에 표시하지 않습니다.</li>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE}은
+알림 아이콘과 콘텐츠 제목 등의 기본 정보는 표시하지만 알림의 전체 콘텐츠는 숨깁니다.</li>
+</ul>
+
+<p>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE}으로 설정하면 ,
+알림 콘텐츠의 대체 버전을 제공할 수도 있습니다. 이렇게 하면 특정 세부 사항만 숨깁니다. 예를 들어,
+SMS 앱에서 <em>3개의 새 문자 메시지가 있습니다.</em>라고 표시하면서도
+문자 메시지의 내용과 발신자는 숨길 수 있습니다. 이 대체 알림을 제공하려면, 우선 대체 알림을 생성합니다. 이때
+{@link android.support.v4.app.NotificationCompat.Builder}를 사용합니다. 비공개 알림 객체를
+생성하는 경우, 대체 알림을 이에 첨부할 때
+{@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()}
+메서드를 통합니다.</p>
+
+<h3 id="controllingMedia">잠금 화면에서 미디어 재생 제어</h3>
+
+<p>Android 5.0(API 레벨 21)의 잠금 화면에서는 더 이상
+{@link android.media.RemoteControlClient}를 기반으로 한 미디어 제어를 표시하지 않습니다. 이는 사용되지 않고 있기 때문입니다. 대신,
+{@link android.app.Notification.MediaStyle} 템플릿을
+{@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()}
+메서드와 함께 사용하십시오. 이 메서드는 작업을 클릭할 수 있는 아이콘으로 변환해줍니다.</p>
+
+<p class="note"><strong>참고:</strong> 이 템플릿과 {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()}
+메서드는 지원 라이브러리에 포함되어 있지 않으므로 이 기능은 Android 5.0 이상에서만
+실행됩니다.</p>
+
+<p>Android 5.0의 잠금 화면에서 미디어 재생 제어를 표시하려면,
+위에 설명한 바와 같이 가시성을 {@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC}으로 설정합니다. 그런 다음 다음 샘플 코드에서 설명한 바와 같이 작업을 추가하고
+{@link android.app.Notification.MediaStyle} 템플릿을 설정합니다.
+</p>
+
+<pre>
+Notification notification = new Notification.Builder(context)
+ // Show controls on lock screen even when user hides sensitive content.
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setSmallIcon(R.drawable.ic_stat_player)
+ // Add media control buttons that invoke intents in your media service
+ .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
+ .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1
+ .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2
+ // Apply the media style template
+ .setStyle(new Notification.MediaStyle()
+ .setShowActionsInCompactView(1 /* #1: pause button */)
+ .setMediaSession(mMediaSession.getSessionToken())
+ .setContentTitle("Wonderful music")
+ .setContentText("My Awesome Band")
+ .setLargeIcon(albumArtBitmap)
+ .build();
+</pre>
+
+<p class="note"><strong>참고:</strong> {@link android.media.RemoteControlClient}를
+사용하지 않게 된 것은 미디어 제어에 이외에도 더 많은 영향을 미칩니다. 미디어 세션을 관리하고 재생을 제어하기 위한 새 API에 관한 자세한 정보는
+<a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">미디어 재생 제어</a>를
+ 참조하십시오.</p>
+
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="CustomNotification">사용자 지정 알림 레이아웃</h2>
+<p>
+ 알림 프레임워크를 사용하면 사용자 지정 레이아웃을 정의할 수 있습니다.
+사용자 지정 레이아웃은 {@link android.widget.RemoteViews} 객체에서 알림의 외관을 정의합니다.
+ 사용자 지정 레이아웃 알림은 일반적인 알림과 비슷하지만, 이들은 XML 레이아웃 파일에서
+ 정의한 {@link android.widget.RemoteViews}에 기초합니다.
+</p>
+<p>
+ 사용자 지정 알림 레이아웃에 사용할 수 있는 높이는 알림 보기에 따라 다릅니다. 일반
+보기 레이아웃은 64dp로 제한되어 있으며 확장 보기 레이아웃은 256dp로 제한되어 있습니다.
+</p>
+<p>
+ 사용자 지정 레이아웃을 정의하려면
+XML 레이아웃 파일을 팽창하는 {@link android.widget.RemoteViews} 객체를 인스턴트화하는 것부터 시작합니다. 그런 다음,
+
+{@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}과 같은 메서드를 호출하는 대신
+{@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}를 호출합니다. 사용자 지정 알림에서
+콘텐츠 세부 정보를 설정하려면
+{@link android.widget.RemoteViews}의 메서드를 사용하여 보기의 하위 요소에 대한 값을 설정합니다.
+</p>
+<ol>
+ <li>
+ 알림에 대한 XML 레이아웃은 별도의 파일에 생성하십시오. 파일 이름은 원하는 대로
+아무 것이나 사용해도 좋지만, 확장자는 <code>.xml</code>을 사용해야 합니다.
+ </li>
+ <li>
+ 앱에서 {@link android.widget.RemoteViews} 메서드를 사용하여 알림의 아이콘과 텍스트를
+정의합니다. 이 {@link android.widget.RemoteViews} 객체를
+{@link android.support.v4.app.NotificationCompat.Builder} 안에 넣으십시오.
+{@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}를 호출하면 됩니다. 배경
+{@link android.graphics.drawable.Drawable}을
+{@link android.widget.RemoteViews} 객체에서 설정하는 것은 삼가하십시오. 텍스트 색상을 읽을 수 없게 될 수도 있습니다.
+ </li>
+</ol>
+<p>
+ {@link android.widget.RemoteViews} 클래스에도 개발자가 손쉽게 사용할 수 있는 여러 가지 메서드가 포함되어 있습니다. 이를 이용해
+{@link android.widget.Chronometer} 또는 {@link android.widget.ProgressBar}를
+알림의 레이아웃에 추가하면 됩니다. 알림의 사용자 지정 레이아웃 생성에 관한 자세한 정보는
+{@link android.widget.RemoteViews} 참조 문서를 참조하십시오.
+</p>
+<p class="caution">
+ <strong>주의:</strong> 사용자 지정 레이아웃을 사용하는 경우,
+사용자 지정 레이아웃이 다양한 기기 방향과 해상도에서 작동하는지 각별히 주의를 기울여 확인하십시오. 이 조언은
+모든 보기 레이아웃에 공통적으로 적용되지만, 특히 알림에 중요한 의미를 지닙니다.
+알림 창에서는 공간이 굉장히 제한되어 있기 때문입니다. 사용자 지정 레이아웃을 너무 복잡하게 만들지 마시고,
+여러 가지 구성에서 테스트하는 것을 잊지 마십시오.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h4>사용자 지정 알림 텍스트에 스타일 리소스 사용</h4>
+<p>
+ 사용자 지정 알림의 텍스트에는 항상 스타일 리소스를 사용하십시오. 알림의 배경 색상은 기기와 버전별로 다를 수 있습니다.
+스타일 리소스를 사용하면 이러한 차이를
+감안하는 데 도움이 됩니다. Android 2.3부터 시스템은
+표준 알림 레이아웃 텍스트의 스타일을 정의했습니다. Android 2.3 이상을 대상으로 하는
+애플리케이션에서와 같은 스타일을 사용하면 텍스트가 디스플레이 배경에서도 잘 보이도록 할 수 있습니다.
+</p>
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/overview.jd b/docs/html-intl/intl/ko/guide/topics/ui/overview.jd
new file mode 100644
index 000000000000..eb288f1532ae
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/overview.jd
@@ -0,0 +1,71 @@
+page.title=UI 개요
+@jd:body
+
+
+<p>Android 앱의 모든 사용자 인터페이스 요소는 {@link android.view.View}와
+{@link android.view.ViewGroup} 개체를 사용하여 구축합니다. {@link android.view.View}는 사용자가 상호 작용할 수 있는 무언가를
+화면에 그리는 객체입니다. {@link android.view.ViewGroup}은
+인터페이스 레이아웃을 정의하기 위해 다른 {@link android.view.View}(및{@link android.view.ViewGroup}) 객체를
+보유하는 객체입니다.</p>
+
+<p>Android는 공통 입력 제어(버튼 및 텍스트 필드)와 다양한 레이아웃 모델(선형 또는 관계 레이아웃)을 제공하는 {@link android.view.View}와 {@link
+android.view.ViewGroup} 하위 클래스의
+컬렉션을 제공합니다.</p>
+
+
+<h2 id="Layout">사용자 인터페이스 레이아웃</h2>
+
+<p>앱의 각 구성 요소에 대한 사용자 인터페이스는 그림 1에서 나타난 바와 같이 {@link
+android.view.View}와 {@link android.view.ViewGroup} 객체의 계층으로 정의됩니다. 각 보기 그룹은
+하위 보기를 체계화하는 투명한 컨테이너이고,
+하위 보기는 UI의 일부분을 그리는 제어나 다른 위젯일 수 있습니다.
+이 계층 트리는 개발자에게 필요한 만큼 단순하거나 복잡하게
+만들 수 있습니다(다만 단순한 것이 성능에는 가장 좋습니다).</p>
+
+<img src="{@docRoot}images/viewgroup.png" alt="" />
+<p class="img-caption"><strong>그림 1.</strong> 보기 계층을 나타낸 것으로, 이것이
+UI 레이아웃을 정의합니다.</p>
+
+<p>레이아웃을 선언하려면 코드의 {@link android.view.View} 객체를 인스턴트화하고 트리를 구축하기 시작하면 되지만,
+레이아웃을 정의하는 가장 쉽고 효과적인 방법은 XML 파일을 사용하는 것입니다.
+XML은 HTML과 유사한, 인간이 읽을 수 있는 레이아웃 구조를 제공합니다.</p>
+
+<p>보기의 XML 요소 이름은 해당 요소가 나타내는 각각의 Android 클래스를 따릅니다. 말하자면
+<code>&lt;TextView&gt;</code> 요소가 UI에서 {@link android.widget.TextView} 위젯을 생성하고,
+<code>&lt;LinearLayout&gt;</code> 요소는 {@link android.widget.LinearLayout} 보기
+그룹을 생성하는 것입니다. </p>
+
+<p>예를 들어, 텍스트 보기와 버튼 하나가 있는 단순한 수직 레이아웃은 이런 모습을 띱니다.</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+ &lt;TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="I am a TextView" />
+ &lt;Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="I am a Button" />
+&lt;/LinearLayout>
+</pre>
+
+<p>앱에 레이아웃 리소스를 로드하면 Android가 레이아웃의 각 노드를 초기화하여
+추가 동작을 정의하거나, 객체 상태를 쿼리 또는 레이아웃을 수정하는 데 쓸 수 있는 런타임 객체로
+초기화합니다.</p>
+
+<p>UI 레이아웃 생성에 대한 완전한 가이드는 <a href="declaring-layout.html">XML
+레이아웃</a>을 참조하십시오.
+
+
+<h2 id="UIComponents">사용자 인터페이스 구성 요소</h2>
+
+<p>UI를 구축할 때 모두 {@link android.view.View} 및 {@link
+android.view.ViewGroup} 객체를 사용해야 하는 것은 아닙니다. Android가 표준형 UI 레이아웃을 제공하는 앱 구성 요소를 여러 개 제공하고 있으니,
+개발자 여러분은 이에 대한 콘텐츠만 정의하면 됩니다. 이와 같은 UI 구성 요소에는 각각
+고유한 API 세트가 있습니다. 이들은 <a href="{@docRoot}guide/topics/ui/actionbar.html">작업 모음</a>, <a href="{@docRoot}guide/topics/ui/dialogs.html">대화</a> 및 <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">상태 알림</a> 등 각각 다른 문서에서 설명하였습니다.</p>
+
+
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/settings.jd b/docs/html-intl/intl/ko/guide/topics/ui/settings.jd
new file mode 100644
index 000000000000..36204e03ecf5
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/settings.jd
@@ -0,0 +1,1202 @@
+page.title=설정
+page.tags=preference,preferenceactivity,preferencefragment
+
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>이 문서의 내용</h2>
+<ol>
+ <li><a href="#Overview">개요</a>
+ <ol>
+ <li><a href="#SettingTypes">기본 설정</a></li>
+ </ol>
+ </li>
+ <li><a href="#DefiningPrefs">XML로 기본 설정 정의하기</a>
+ <ol>
+ <li><a href="#Groups">설정 그룹 만들기</a></li>
+ <li><a href="#Intents">인텐트 사용하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#Activity">기본 설정 액티비티 만들기</a></li>
+ <li><a href="#Fragment">기본 설정 프래그먼트 사용하기</a></li>
+ <li><a href="#Defaults">설정 기본 값</a></li>
+ <li><a href="#PreferenceHeaders">기본 설정 헤더 사용하기</a>
+ <ol>
+ <li><a href="#CreateHeaders">헤더 파일 만들기</a></li>
+ <li><a href="#DisplayHeaders">헤더 표시하기</a></li>
+ <li><a href="#BackCompatHeaders">기본 설정 헤더로 이전 버전 지원하기</a></li>
+ </ol>
+ </li>
+ <li><a href="#ReadingPrefs">기본 설정 읽기</a>
+ <ol>
+ <li><a href="#Listening">기본 설정 변경 수신 대기</a></li>
+ </ol>
+ </li>
+ <li><a href="#NetworkUsage">네트워크 사용량 관리하기</a></li>
+ <li><a href="#Custom">사용자 지정 기본 설정 구축하기</a>
+ <ol>
+ <li><a href="#CustomSelected">사용자 인터페이스 지정하기</a></li>
+ <li><a href="#CustomSave">설정의 값 저장하기</a></li>
+ <li><a href="#CustomInitialize">현재 값 초기화하기</a></li>
+ <li><a href="#CustomDefault">기본 값 제공하기</a></li>
+ <li><a href="#CustomSaveState">기본 설정의 상태 저장 및 복원하기</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Key 클래스</h2>
+<ol>
+ <li>{@link android.preference.Preference}</li>
+ <li>{@link android.preference.PreferenceActivity}</li>
+ <li>{@link android.preference.PreferenceFragment}</li>
+</ol>
+
+
+<h2>참고 항목</h2>
+<ol>
+ <li><a href="{@docRoot}design/patterns/settings.html">설정 디자인 가이드</a></li>
+</ol>
+</div>
+</div>
+
+
+
+
+<p>애플리케이션에는 종종 설정이 포함되어 있어 사용자가 앱 기능과 행동을 수정할 수 있게 해줍니다. 예를 들어
+몇몇 앱은 사용자에게 알림을 활성화할지 여부를 지정하거나 애플리케이션이
+클라우드와 데이터를 동기화할 빈도를 지정할 수 있게 해줍니다.</p>
+
+<p>자신의 앱에 설정을 제공하고자 하는 경우, Android의
+{@link android.preference.Preference} API를 사용하여 다른 Android 앱(시스템 설정 포함)의 사용자 환경과
+일관성을 유지하는 인터페이스를 구축할 수 있게 해야 합니다. 이 문서에서는
+{@link android.preference.Preference} API를 사용하여 앱 설정을 구축하는 방법을 설명합니다.</p>
+
+<div class="note design">
+<p><strong>설정 디자인</strong></p>
+ <p>설정을 디자인하는 방법에 관련된 정보는 <a href="{@docRoot}design/patterns/settings.html">설정</a> 디자인 가이드를 읽어보십시오.</p>
+</div>
+
+
+<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" />
+<p class="img-caption"><strong>그림 1.</strong> Android 메시지 앱의 설정에서 가져온
+스크린샷입니다. {@link android.preference.Preference}가 정의한 항목을 선택하면
+인터페이스가 열려 설정을 변경할 수 있게 됩니다.</p>
+
+
+
+
+<h2 id="Overview">개요</h2>
+
+<p>사용자 인터페이스를 구축할 때에는 {@link android.view.View} 객체를 사용하지만, 설정은 그 대신
+{@link android.preference.Preference} 클래스의 다양한 하위 클래스를 사용하여 구축합니다.
+이와 같은 하위 클래스는 XML 파일에서 선언합니다.</p>
+
+<p>{@link android.preference.Preference} 객체는 하나의 설정을 이루는 기본
+단위입니다. 각각의 {@link android.preference.Preference}는 목록의 항목으로
+나타나며 사용자가 설정을 수정하기에 적절한 UI를 제공합니다. 예를 들어 {@link
+android.preference.CheckBoxPreference}는 확인란을 표시하는 목록 항목을 만들고, {@link
+android.preference.ListPreference}는 선택 목록이 있는 대화를 여는 항목을 만듭니다.</p>
+
+<p>각각의 {@link android.preference.Preference}를 추가할 때마다 상응하는 키-값 쌍이 있어
+시스템이 이를 사용하여 해당 설정을 앱의 설정에 대한 기본 {@link android.content.SharedPreferences}
+파일에 저장합니다. 사용자가 설정을 변경하면 시스템이
+{@link android.content.SharedPreferences} 파일에 있는 상응하는 값을 개발자 대신 업데이트합니다. 개발자가 직접
+연관된 {@link android.content.SharedPreferences} 파일과 상호 작용을 해야 하는 경우는
+사용자의 설정을 기반으로 앱의 동작을 결정하기 위해 값을 읽어야 할 때뿐입니다.</p>
+
+<p>각 설정에 대하여 {@link android.content.SharedPreferences}에 저장된 값은 다음과 같은
+데이터 유형 중 한 가지를 취할 수 있습니다.</p>
+
+<ul>
+ <li>Boolean</li>
+ <li>Float</li>
+ <li>Int</li>
+ <li>Long</li>
+ <li>String</li>
+ <li>String {@link java.util.Set}</li>
+</ul>
+
+<p>앱의 설정 UI는
+{@link android.view.View} 객체 대신
+{@link android.preference.Preference} 객체를 사용하여 구축되기 때문에, 목록 설정을 표시하려면 특수 {@link android.app.Activity} 또는
+{@link android.app.Fragment} 하위 클래스를 사용해야 합니다.</p>
+
+<ul>
+ <li>앱이 Android 3.0 이전 버전(API 레벨 10 이하)을 지원하는 경우, 액티비티를 구축할 때
+{@link android.preference.PreferenceActivity} 클래스의 확장으로 구축해야 합니다.</li>
+ <li>Android 3.0 이후의 경우에는 대신 기존의 {@link android.app.Activity}를
+사용해야 합니다. 이것은 앱 설정을 표시하는 {@link android.preference.PreferenceFragment}를 호스팅합니다.
+하지만, 여러 개의 설정 그룹이 있는 경우 {@link android.preference.PreferenceActivity}를 사용하여
+대형 화면에 맞는 창 두 개짜리 레이아웃을 만들 수도 있습니다.</li>
+</ul>
+
+<p>{@link android.preference.PreferenceActivity}와 {@link
+android.preference.PreferenceFragment}의 인스턴스를 설정하는 방법은 <a href="#Activity">기본 설정 액티비티 만들기</a>와 <a href="#Fragment">기본 설정
+프래그먼트 사용하기</a>에 관련된 섹션에서 논합니다.</p>
+
+
+<h3 id="SettingTypes">기본 설정</h3>
+
+<p>앱에 대한 설정은 모두 {@link
+android.preference.Preference} 클래스의 특정 하위 클래스로 표현됩니다. 각 하위 클래스에 핵심 속성이 한 세트씩 포함되어 있어
+설정의 제목과 기본 값 등과 같은 것을 지정할 수 있게 해줍니다. 각 하위 클래스는 또한 자신만의
+특수 속성과 사용자 인터페이스도 제공합니다. 예를 들어, 그림 1에서는 메시지 앱의 설정에서
+가져온 스크린샷을 나타낸 것입니다. 설정 화면에 있는 각 목록 항목은 각기 서로 다른 {@link
+android.preference.Preference} 객체로 지원됩니다.</p>
+
+<p>가장 보편적인 기본 설정을 몇 가지만 소개하면 다음과 같습니다.</p>
+
+<dl>
+ <dt>{@link android.preference.CheckBoxPreference}</dt>
+ <dd>활성화되었거나 비활성화된 설정에 대한 확인란이 있는 항목을 표시합니다. 저장된 값은
+부울입니다(확인란이 선택된 경우 <code>true</code>).</dd>
+
+ <dt>{@link android.preference.ListPreference}</dt>
+ <dd>무선 버튼 목록이 있는 대화를 엽니다. 저장된 값은
+지원되는 값 유형(위에 목록으로 나열) 중 어느 것이라도 될 수 있습니다.</dd>
+
+ <dt>{@link android.preference.EditTextPreference}</dt>
+ <dd>{@link android.widget.EditText} 위젯이 있는 대화를 엽니다. 저장된 값은 {@link
+java.lang.String}입니다.</dd>
+</dl>
+
+<p>다른 모든 하위 클래스와 이에 상응하는 속성의 목록을 보려면 {@link android.preference.Preference}
+ 클래스를 참조하십시오.</p>
+
+<p>물론 기본 제공 클래스만으로는 필요한 것을 모두 충족할 수 없고 앱에 무언가 좀 더 특수한 것이
+필요할 수도 있습니다. 예를 들어 플랫폼은 현재 숫자나 날짜를 선택할 수 있는 {@link
+android.preference.Preference} 클래스를 제공하지 않습니다. 따라서 개발자 나름대로
+{@link android.preference.Preference} 하위 클래스를 정의해야 할 수도 있습니다. 이 작업을 수행하는 데 유용한 내용인 <a href="#Custom">사용자 지정 기본 설정 구축하기</a>에 관한 섹션을 참조하십시오.</p>
+
+
+
+<h2 id="DefiningPrefs">XML로 기본 설정 정의하기</h2>
+
+<p>새로운 {@link android.preference.Preference} 객체를 런타임에 인스턴트화하는 것도 가능하지만,
+설정 목록을 정의할 때에는 {@link android.preference.Preference}
+객체의 계층과 함께 XML을 사용해야 합니다. 설정 컬렉션을 정의하는 데 XM 파일을 사용하는 것이 선호되는 이유는 이 파일이
+읽기 쉬운 구조를 제공하여 업데이트가 단순하기 때문입니다. 또한, 앱의 설정은 보통
+미리 정의되어 있습니다. 다만 개발자도 여전히 런타임에 설정 컬렉션을 수정할 수 있습니다.</p>
+
+<p>각 {@link android.preference.Preference} 하위 클래스는 클래스 이름에 일치하는 XML 요소로
+선언하면 됩니다. 예를 들면 {@code &lt;CheckBoxPreference&gt;}가 이에 해당됩니다.</p>
+
+<p>이 XML 파일은 반드시 {@code res/xml/} 디렉터리에 저장해야 합니다. 파일의 이름은 무엇이든 원하는 대로 지정할 수 있지만,
+일반적으로는 {@code preferences.xml}이라고 명명합니다. 파일은 하나만 필요한 것이 보통입니다.
+왜냐하면 계층에 있는 분기(자신만의 설정 목록을 엶)는
+{@link android.preference.PreferenceScreen}의 중첩된 인스턴스를 사용하여 선언되기 때문입니다.</p>
+
+<p class="note"><strong>참고:</strong> 설정에 다중 창 레이아웃을 만들고자 하는 경우,
+각 프래그먼트에 대해 별도의 XML 파일이 필요합니다.</p>
+
+<p>XML 파일의 루트 노드는 반드시 {@link android.preference.PreferenceScreen
+&lt;PreferenceScreen&gt;} 요소여야 합니다. 바로 이 요소 내에 각 {@link
+android.preference.Preference}를 추가하는 것입니다.
+{@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} 요소 내에 추가하는 각 하위는 설정 목록에서
+각기 항목 하나씩으로 나타납니다.</p>
+
+<p>예:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;CheckBoxPreference
+ android:key="pref_sync"
+ android:title="@string/pref_sync"
+ android:summary="@string/pref_sync_summ"
+ android:defaultValue="true" />
+ &lt;ListPreference
+ android:dependency="pref_sync"
+ android:key="pref_syncConnectionType"
+ android:title="@string/pref_syncConnectionType"
+ android:dialogTitle="@string/pref_syncConnectionType"
+ android:entries="@array/pref_syncConnectionTypes_entries"
+ android:entryValues="@array/pref_syncConnectionTypes_values"
+ android:defaultValue="@string/pref_syncConnectionTypes_default" />
+&lt;/PreferenceScreen>
+</pre>
+
+<p>이 예시에서는 {@link android.preference.CheckBoxPreference}와 {@link
+android.preference.ListPreference}가 하나씩 있습니다. 두 항목 모두 다음과 같은 세 가지 속성을 포함하고 있습니다.</p>
+
+<dl>
+ <dt>{@code android:key}</dt>
+ <dd>이 속성은 데이터 값을 유지하는 기본 설정에 필수입니다. 이것은 고유키(문자)를
+나타내며, 시스템이 이것을 사용하여 이 설정의 값을 {@link
+android.content.SharedPreferences}에 저장합니다.
+ <p>이 속성이 <em>필요하지 않은</em> 인스턴스는 기본 설정이
+{@link android.preference.PreferenceCategory} 또는 {@link android.preference.PreferenceScreen}인 경우, 또는
+기본 설정이 {@link android.content.Intent}를 호출할 것을 나타내거나(<a href="#Intents">{@code &lt;intent&gt;}</a> 요소로) {@link android.app.Fragment}를 표시하도록 지정하는 경우(<a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code
+android:fragment}</a> 속성으로)뿐입니다.</p>
+ </dd>
+ <dt>{@code android:title}</dt>
+ <dd>이것은 설정에 대하여 사용자가 볼 수 있는 이름을 제공합니다.</dd>
+ <dt>{@code android:defaultValue}</dt>
+ <dd>이것은 시스템이 {@link
+android.content.SharedPreferences} 파일에 설정해야 하는 초기 값을 나타냅니다. 모든 설정에 기본 값을 제공해야
+합니다.</dd>
+</dl>
+
+<p>다른 모든 지원되는 속성에 대해서는 {@link
+android.preference.Preference}(및 각각의 하위 클래스) 관련 문서를 참조하십시오.</p>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" />
+ <p class="img-caption"><strong>그림 2.</strong> 제목이 있는 설정
+카테고리입니다. <br/><b>1.</b> 카테고리는 {@link
+android.preference.PreferenceCategory &lt;PreferenceCategory&gt;} 요소가 지정합니다. <br/><b>2.</b> 제목은
+{@code android:title} 속성으로 지정합니다.</p>
+</div>
+
+
+<p>설정 목록이 약 10개 항목을 초과하면 제목을 추가하여
+설정 그룹을 정의하거나, 해당 그룹을 별도의
+화면에 표시하는 것이 좋을 수도 있습니다. 이러한 옵션은 다음 섹션에 설명되어 있습니다.</p>
+
+
+<h3 id="Groups">설정 그룹 만들기</h3>
+
+<p>10개 이상의 설정 목록을 제시하는 경우, 사용자가
+이들을 둘러보고 이해하며 처리하는 데 어려움을 겪을 수 있습니다. 이 문제를 해결하려면
+설정의 일부 또는 모두를 그룹으로 나누어 사실상 하나의 긴 목록을 여러 개의 더 짧은 목록으로
+바꿔주면 됩니다. 관련된 설정 그룹 하나를 나타낼 때에는 다음과 같은 두 가지 방식 중 하나를 택하면 됩니다.</p>
+
+<ul>
+ <li><a href="#Titles">제목 사용하기</a></li>
+ <li><a href="#Subscreens">보조 화면 사용하기</a></li>
+</ul>
+
+<p>이와 같은 그룹화 기법 중 하나 또는 둘 모두를 사용하여 앱의 설정을 조직화할 수 있습니다. 어느 것을
+사용할지, 설정을 어떻게 나눌지 결정할 때에는 Android
+디자인의 <a href="{@docRoot}design/patterns/settings.html">설정</a> 가이드에 있는 지침을 따라야 합니다.</p>
+
+
+<h4 id="Titles">제목 사용하기</h4>
+
+<p>여러 개의 설정 그룹 사이에 구분선과 제목을 제공하고자 하는 경우(그림 2에 표시된 것과 같이),
+각 {@link android.preference.Preference} 객체 그룹을 {@link
+android.preference.PreferenceCategory} 내부에 배치합니다.</p>
+
+<p>예:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;PreferenceCategory
+ android:title="&#64;string/pref_sms_storage_title"
+ android:key="pref_key_storage_settings">
+ &lt;CheckBoxPreference
+ android:key="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_auto_delete"
+ android:title="&#64;string/pref_title_auto_delete"
+ android:defaultValue="false"... />
+ &lt;Preference
+ android:key="pref_key_sms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_sms_delete"... />
+ &lt;Preference
+ android:key="pref_key_mms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_mms_delete" ... />
+ &lt;/PreferenceCategory>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h4 id="Subscreens">보조 화면 사용하기</h4>
+
+<p>설정 그룹 여러 개를 보조 화면에 배치하고자 하는 경우(그림 3에 표시된 것과 같이), 해당
+{@link android.preference.Preference} 객체 그룹을 {@link
+android.preference.PreferenceScreen} 안에 배치합니다.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" />
+<p class="img-caption"><strong>그림 3.</strong> 설정 보조 화면입니다. {@code
+&lt;PreferenceScreen&gt;} 요소가
+항목을 만들며, 이 항목이 선택되면 별도의 목록이 열려 중첩된 설정을 표시합니다.</p>
+
+<p>예:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;!-- opens a subscreen of settings -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_category_key"
+ android:title="&#64;string/voicemail"
+ android:persistent="false">
+ &lt;ListPreference
+ android:key="button_voicemail_provider_key"
+ android:title="&#64;string/voicemail_provider" ... />
+ &lt;!-- opens another nested subscreen -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_setting_key"
+ android:title="&#64;string/voicemail_settings"
+ android:persistent="false">
+ ...
+ &lt;/PreferenceScreen>
+ &lt;RingtonePreference
+ android:key="button_voicemail_ringtone_key"
+ android:title="&#64;string/voicemail_ringtone_title"
+ android:ringtoneType="notification" ... />
+ ...
+ &lt;/PreferenceScreen>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h3 id="Intents">인텐트 사용하기</h3>
+
+<p>어떤 경우에는 기본 설정 항목을 사용하여 설정 화면 대신 여러 가지 액티비티를
+열고자 할 수도 있습니다. 예를 들어 웹 브라우저를 열어 웹 페이지를 보는 것이 이에 해당됩니다. 사용자가 기본 설정 항목을 선택할 때 {@link
+android.content.Intent}를 호출하도록 하려면, {@code &lt;intent&gt;}
+요소를 상응하는 {@code &lt;Preference&gt;} 요소의 하위로 추가하면 됩니다.</p>
+
+<p>예를 들어 다음은 기본 설정 항목을 사용하여 웹 페이지를 열도록 하는 방법입니다.</p>
+
+<pre>
+&lt;Preference android:title="@string/prefs_web_page" >
+ &lt;intent android:action="android.intent.action.VIEW"
+ android:data="http://www.example.com" />
+&lt;/Preference>
+</pre>
+
+<p>다음 속성을 사용하여 명시적 인텐트와 암시적 인텐트 두 가지를 모두 만들 수 있습니다.</p>
+
+<dl>
+ <dt>{@code android:action}</dt>
+ <dd>할당할 작업이며, {@link android.content.Intent#setAction setAction()}
+메서드를 따릅니다.</dd>
+ <dt>{@code android:data}</dt>
+ <dd>할당할 데이터이며, {@link android.content.Intent#setData setData()} 메서드를 따릅니다.</dd>
+ <dt>{@code android:mimeType}</dt>
+ <dd>할당할 MIME 유형이며, {@link android.content.Intent#setType setType()}
+메서드를 따릅니다.</dd>
+ <dt>{@code android:targetClass}</dt>
+ <dd>구성 요소 이름의 클래스 부분이며, {@link android.content.Intent#setComponent
+setComponent()} 메서드를 따릅니다.</dd>
+ <dt>{@code android:targetPackage}</dt>
+ <dd>구성 요소 이름의 패키지 부분이며, {@link
+android.content.Intent#setComponent setComponent()} 메서드를 따릅니다.</dd>
+</dl>
+
+
+
+<h2 id="Activity">기본 설정 액티비티 만들기</h2>
+
+<p>설정을 액티비티에서 표시하려면 {@link
+android.preference.PreferenceActivity} 클래스를 확장하면 됩니다. 이것은 일반적인 {@link
+android.app.Activity} 클래스 확장의 일종입니다. 이는 {@link
+android.preference.Preference} 객체의 계층에 기반한 설정 목록을 표시합니다. {@link android.preference.PreferenceActivity}는
+사용자가 변경 작업을 하면 각 {@link
+android.preference.Preference}와 연관된 설정을 유지합니다.</p>
+
+<p class="note"><strong>참고:</strong> Android 3.0 이상에 맞춰 애플리케이션을 개발하는 경우,
+대신 {@link android.preference.PreferenceFragment}를 사용해야 합니다. 다음 섹션의
+<a href="#Fragment">기본 설정 프래그먼트 사용하기</a> 관련 내용을 참조하십시오.</p>
+
+<p>여기서 기억해야 할 가장 중요한 점은 {@link
+android.preference.PreferenceActivity#onCreate onCreate()} 콜백 중에 보기 레이아웃을 로딩해서는 안 된다는 것입니다. 그 대신 {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}를 호출하여
+XML 파일에서 선언한 기본 설정을 액티비티에 추가합니다. 예를 들어 다음은 기능적인
+{@link android.preference.PreferenceActivity}에 필요한 가장 최소한의 코드를 나타낸 것입니다.</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
+</pre>
+
+<p>사실 이 코드만으로 몇몇 앱에는 충분합니다. 사용자가 기본 설정을 수정하자마자
+시스템이 해당 변경을 기본 {@link android.content.SharedPreferences} 파일에 저장하여,
+사용자의 설정을 확인해야 할 때 다른 애플리케이션 구성 요소가 이를 읽을 수 있도록 하기 때문입니다. 하지만
+대다수의 앱은 기본 설정에 일어나는 변경을 수신 대기하기 위해 약간의 코드가 더 필요합니다.
+{@link android.content.SharedPreferences} 파일에 일어나는 변경을 수신 대기하는 데 관한
+자세한 정보는 <a href="#ReadingPrefs">기본 설정 읽기</a>에 관한 섹션을 참조하십시오.</p>
+
+
+
+
+<h2 id="Fragment">기본 설정 프래그먼트 사용하기</h2>
+
+<p>Android 3.0(API 레벨 11) 이상에 맞춰 개발하는 경우, {@link
+android.preference.PreferenceFragment}를 사용하여 {@link android.preference.Preference}
+객체 목록을 표시해야 합니다. {@link android.preference.PreferenceFragment}는 모든 액티비티에 추가할 수 있습니다. 즉,
+{@link android.preference.PreferenceActivity}를 사용하지 않아도 됩니다.</p>
+
+<p><a href="{@docRoot}guide/components/fragments.html">프래그먼트</a>는 액티비티만
+사용하는 것에 비해 애플리케이션에 보다 유연한 아키텍처를 제공하며, 이는 구축하는
+액티비티의 종류와 무관하게 적용됩니다. 따라서 설정 표시를 제어하는 데에는 {@link
+android.preference.PreferenceFragment}를 {@link
+android.preference.PreferenceActivity} 대신 사용하는 방안을 권장합니다(가능한 경우).</p>
+
+<p>{@link android.preference.PreferenceFragment} 구현은 매우 간단합니다.
+{@link android.preference.PreferenceFragment#onCreate onCreate()} 메서드를 정의하여 기본 설정 파일을
+{@link android.preference.PreferenceFragment#addPreferencesFromResource
+addPreferencesFromResource()}로 로딩하도록 하기만 하면 됩니다. 예:</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+}
+</pre>
+
+<p>그런 다음 이 프래그먼트를 {@link android.app.Activity}에 추가하기만 하면 되고, 이는 다른 모든
+{@link android.app.Fragment}에서와 마찬가지입니다. 예:</p>
+
+<pre>
+public class SettingsActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Display the fragment as the main content.
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new SettingsFragment())
+ .commit();
+ }
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> {@link android.preference.PreferenceFragment}에는 자신만의
+{@link android.content.Context} 객체가 없습니다. {@link android.content.Context}
+객체가 필요한 경우, {@link android.app.Fragment#getActivity()}를 호출하면 됩니다. 하지만,
+{@link android.app.Fragment#getActivity()}를 호출하는 것은 프래그먼트가 액티비티에 첨부되어 있는 경우만으로 국한시켜야 한다는 점을 유의하십시오. 프래그먼트가
+아직 첨부되지 않았거나 수명 주기가 끝날 무렵 분리된 경우, {@link
+android.app.Fragment#getActivity()}가 null을 반환합니다.</p>
+
+
+<h2 id="Defaults">설정 기본 값</h2>
+
+<p>여러분이 만드는 기본 설정은 애플리케이션에 중요한 동작을 정의하는 경우가 많을 것입니다. 따라서
+연관된 {@link android.content.SharedPreferences} 파일을
+각 {@link android.preference.Preference}에 대한 기본 값으로 초기화하여 사용자가 애플리케이션을 처음 열 때
+적용하는 것이 중요합니다.</p>
+
+<p>가장 먼저 해야 할 일은 XML 파일 내의 각 {@link
+android.preference.Preference}
+객체에 대해 기본 값을 지정하는 것입니다. 이때 {@code android:defaultValue} 속성을 사용합니다. 이 값은 상응하는
+{@link android.preference.Preference} 객체에 대해 적절한 어느 데이터 유형이라도 될 수 있습니다. 예:
+</p>
+
+<pre>
+&lt;!-- default value is a boolean -->
+&lt;CheckBoxPreference
+ android:defaultValue="true"
+ ... />
+
+&lt;!-- default value is a string -->
+&lt;ListPreference
+ android:defaultValue="@string/pref_syncConnectionTypes_default"
+ ... />
+</pre>
+
+<p>그런 다음, 애플리케이션의 기본 액티비티에 있는 {@link android.app.Activity#onCreate onCreate()}
+메서드로부터&mdash;또한 사용자가 애플리케이션에 처음으로 들어올 통로가 될 수 있는
+다른 모든 액티비티도 포함&mdash;{@link android.preference.PreferenceManager#setDefaultValues
+setDefaultValues()}를 호출합니다.</p>
+
+<pre>
+PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
+</pre>
+
+<p>이것을 {@link android.app.Activity#onCreate onCreate()} 중에 호출하면
+애플리케이션이 기본 설정으로 적절히 초기화되도록 보장할 수 있습니다. 이것은 애플리케이션이
+몇 가지 동작을 결정하기 위해 읽어야 할 수도 있습니다(예를 들어 셀룰러 네트워크에서 데이터를
+다운로드할지 여부 등).</p>
+
+<p>이 메서드는 다음과 같은 세 개의 인수를 취합니다.</p>
+<ul>
+ <li>애플리케이션 {@link android.content.Context}.</li>
+ <li>기본 값을 설정하고자 하는 기본 설정 XML 파일에 대한 리소스 ID입니다.</li>
+ <li>기본 값을 한 번 이상 설정해야 하는지 여부를 나타내는 부울 값입니다.
+<p><code>false</code>인 경우, 시스템은 이 메서드가 전에 한 번도 호출된 적이 없을 경우에만
+기본 값을 설정합니다(아니면 기본 값을 공유한 기본 설정 파일에 있는 {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES}
+가 안전합니다).</p></li>
+</ul>
+
+<p>세 번째 인수를 <code>false</code>로 설정해 두는 한 이 메서드를 액티비티가 시작될 때마다
+안전하게 호출할 수 있으며, 그렇게 해도 사용자의 저장된 기본 설정을 기본값으로 초기화하여
+재정의하지 않습니다. 하지만 이를 <code>true</code>로 설정하면, 이전의 모든 값을
+기본 값으로 재정의하게 됩니다.</p>
+
+
+
+<h2 id="PreferenceHeaders">기본 설정 헤더 사용하기</h2>
+
+<p>드문 경우지만 설정을 디자인할 때 첫 화면에는
+<a href="#Subscreens">보조 화면</a> 목록만 표시하도록 하고자 할 수도 있습니다(예: 시스템 설정 앱,
+그림 4와 5 참조). 그러한 디자인을 Android 3.0 이상을 대상으로 개발하는 경우, Android 3.0에 있는
+새로운 "헤더" 기능을 사용해야 합니다. 이것이 중첩된
+{@link android.preference.PreferenceScreen} 요소를 사용하여 보조 화면을 구축하는 방안을 대신합니다.</p>
+
+<p>헤더를 사용하여 설정을 구축하려면 다음과 같이 해야 합니다.</p>
+<ol>
+ <li>각 설정 그룹을 별개의 {@link
+android.preference.PreferenceFragment} 인스턴스로 구분합니다. 다시 말해, 설정 그룹마다 별도의 XML 파일이 하나씩 있어야 한다는
+뜻입니다.</li>
+ <li>각 설정 그룹을 목록으로 나열하는 XML 헤더 파일을 생성하고 어느 프래그먼트에
+상응하는 설정 목록이 들어있는지 선언합니다.</li>
+ <li>{@link android.preference.PreferenceActivity} 클래스를 확장하여 설정을 호스팅하도록 합니다.</li>
+ <li>{@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} 콜백을 구현하여 헤더 파일을
+나타냅니다.</li>
+</ol>
+
+<p>이 디자인을 사용하는 데 있어 커다란 이점은 {@link android.preference.PreferenceActivity}가
+(앱이) 대형 화면에서 실행될 때 그림 4에서 나타낸 것과 같이 창 두 개짜리 레이아웃을 자동으로 표시한다는 것입니다.</p>
+
+<p>애플리케이션이 Android 3.0 이전 버전을 지원한다 하더라도 애플리케이션이
+{@link android.preference.PreferenceFragment}를 사용하여
+신형 기기에서 창 두 개짜리 표시를 지원하도록 하면서도 구형 기기에서는 일반적인 다중 화면 계층을
+여전히 지원하도록 할 수도 있습니다(<a href="#BackCompatHeaders">기본 설정 헤더로
+이전 버전 지원하기</a>를 참조하십시오).</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" />
+<p class="img-caption"><strong>그림 4.</strong> 헤더가 있는 창 두 개짜리 레이아웃입니다. <br/><b>1.</b> 헤더는
+XML 헤더 파일로 정의됩니다. <br/><b>2.</b> 각 설정 그룹은
+{@link android.preference.PreferenceFragment}가 정의하며, 이는 헤더 파일에 있는 {@code &lt;header&gt;} 요소가
+지정합니다.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" />
+<p class="img-caption"><strong>그림 5.</strong> 설정 헤더가 있는 핸드셋 기기입니다. 항목을 선택하면
+연관된 {@link android.preference.PreferenceFragment}가 헤더를
+대체합니다.</p>
+
+
+<h3 id="CreateHeaders" style="clear:left">헤더 파일 만들기</h3>
+
+<p>헤더 목록에 있는 각 설정 그룹은 루트 {@code &lt;preference-headers&gt;}
+요소 안에 있는 {@code &lt;header&gt;} 요소 하나로 나타냅니다. 예:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;!-- key/value pairs can be included as arguments for the fragment. -->
+ &lt;extra android:name="someKey" android:value="someHeaderValue" />
+ &lt;/header>
+&lt;/preference-headers>
+</pre>
+
+<p>각 헤더는 {@code android:fragment} 속성으로 {@link
+android.preference.PreferenceFragment} 예를 선언하며 이는 사용자가 헤더를 선택하면 열려야 합니다.</p>
+
+<p>{@code &lt;extras&gt;} 요소를 사용하면 키-값 쌍을 {@link
+android.os.Bundle} 내의 프래그먼트에 전달할 수 있게 해줍니다. 이 프래그먼트가 인수를 검색하려면 {@link
+android.app.Fragment#getArguments()}를 호출하면 됩니다. 인수를 프래그먼트에 전달하는 데에는 여러 가지 이유가 있을 수 있지만,
+한 가지 중요한 이유를 예로 들면 각 그룹에 대해 {@link
+android.preference.PreferenceFragment}의 같은 하위 클래스를 재사용하고, 이 인수를 사용하여 해당 프래그먼트가 로딩해야 하는
+기본 설정 XML 파일이 무엇인지 나타낼 수 있다는 점입니다.</p>
+
+<p>예를 들어 다음은 여러 가지 설정 그룹에 재사용할 수 있는 프래그먼트입니다. 이것은
+각 헤더가 {@code "settings"} 키로 {@code &lt;extra&gt;} 인수를 정의하는 경우를 나타낸 것입니다.</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String settings = getArguments().getString("settings");
+ if ("notifications".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_wifi);
+ } else if ("sync".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_sync);
+ }
+ }
+}
+</pre>
+
+
+
+<h3 id="DisplayHeaders">헤더 표시하기</h3>
+
+<p>기본 설정 헤더를 표시하려면 {@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} 콜백 메서드를 구현하고
+{@link android.preference.PreferenceActivity#loadHeadersFromResource
+loadHeadersFromResource()}를 호출해야 합니다. 예:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+}
+</pre>
+
+<p>사용자가 헤더 목록에서 항목을 하나 선택하면 시스템이 연관된 {@link
+android.preference.PreferenceFragment}를 엽니다.</p>
+
+<p class="note"><strong>참고:</strong> 기본 설정 헤더를 사용하는 경우, {@link
+android.preference.PreferenceActivity}의 하위 클래스가 {@link
+android.preference.PreferenceActivity#onCreate onCreate()} 메서드를 구현하지 않아도 됩니다. 액티비티에 대한 필수 작업은
+헤더를 로딩하는 것뿐이기 때문입니다.</p>
+
+
+<h3 id="BackCompatHeaders">기본 설정 헤더로 이전 버전 지원하기</h3>
+
+<p>애플리케이션이 Android 3.0 이전 버전을 지원하는 경우에도 여전히 헤더를 사용하여
+Android 3.0 이상에서 창 두 개짜리 레이아웃을 제공하도록 할 수 있습니다. 개발자가 해야 할 일은 추가로 기본 설정 XML 파일을
+생성하는 것뿐입니다. 이 파일은 마치 헤더 항목처럼 동작하는 기본적인 {@link android.preference.Preference
+&lt;Preference&gt;} 요소를 사용합니다(이것을 이전 Android 버전이 사용하도록
+할 예정).</p>
+
+<p>하지만 새로운 {@link android.preference.PreferenceScreen}을 여는 대신 각 {@link
+android.preference.Preference &lt;Preference&gt;} 요소가 {@link android.content.Intent}를 하나씩
+{@link android.preference.PreferenceActivity}에 전송합니다. 이것이 로딩할 XML 파일이 무엇인지를
+나타냅니다.</p>
+
+<p>예를 들어 다음은 Android 3.0 이상에서 사용되는 기본 설정 헤더에 대한
+XML 파일입니다({@code res/xml/preference_headers.xml}).</p>
+
+<pre>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" />
+&lt;/preference-headers>
+</pre>
+
+<p>그리고 다음은, Android 3.0 이전 버전에 같은 헤더를 제공하는 기본 설정
+파일입니다({@code res/xml/preference_headers_legacy.xml}).</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;Preference
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_ONE" />
+ &lt;/Preference>
+ &lt;Preference
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_TWO" />
+ &lt;/Preference>
+&lt;/PreferenceScreen>
+</pre>
+
+<p>{@code &lt;preference-headers&gt;}에 대한 지원이 Android 3.0에서 추가되었기 때문에 시스템이
+{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()}를 {@link
+android.preference.PreferenceActivity}에서 호출하는 것은 Android 3.0 이상에서 실행될 때뿐입니다. "레거시" 헤더 파일을
+로딩하려면({@code preference_headers_legacy.xml}) 반드시 Android
+버전을 확인해야 하며, 해당 버전이 Android 3.0 이전인 경우({@link
+android.os.Build.VERSION_CODES#HONEYCOMB}), {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}를 호출하여
+레거시 헤더 파일을 로딩해야 합니다. 예:</p>
+
+<pre>
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ...
+
+ if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+
+// Called only on Honeycomb and later
+&#64;Override
+public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+}
+</pre>
+
+<p>이제 남은 할 일이라고는 {@link android.content.Intent}를 처리하는 것뿐입니다. 이것은
+액티비티로 전달되어 어느 기본 설정 파일을 로딩해야 하는지 식별하는 데 쓰입니다. 그럼 이제 인텐트의 작업을 검색하여 기본 설정 XML의
+{@code &lt;intent&gt;} 태그에서 사용한 알려진 작업 문자열에 비교해보겠습니다.</p>
+
+<pre>
+final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
+...
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String action = getIntent().getAction();
+ if (action != null &amp;&amp; action.equals(ACTION_PREFS_ONE)) {
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+
+ else if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+</pre>
+
+<p>{@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()}를 연이어 호출하면
+모든 기본 설정을 하나의 목록에 쌓게 된다는 점을 유의하십시오. 따라서 이것은 'Else-if' 문이 있는 조건을 변경하여 딱 한 번만
+호출하도록 주의해야 합니다.</p>
+
+
+
+
+
+<h2 id="ReadingPrefs">기본 설정 읽기</h2>
+
+<p>기본적으로 앱의 기본 설정은 모두
+애플리케이션 내의 어디서든 정적 메서드 {@link
+android.preference.PreferenceManager#getDefaultSharedPreferences
+PreferenceManager.getDefaultSharedPreferences()}를 호출하면 액세스할 수 있는 파일에 저장됩니다. 이것은 {@link
+android.content.SharedPreferences} 객체를 반환하며, 여기에 {@link
+android.preference.PreferenceActivity}에서 사용한 {@link android.preference.Preference} 객체와
+연관된 모든 키-값 쌍이 들어있습니다.</p>
+
+<p>예를 들어 다음은 기본 설정 값 중 하나를 애플리케이션 내의 다른 모든 액티비티에서 읽는 방법을
+나타낸 것입니다.</p>
+
+<pre>
+SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");
+</pre>
+
+
+
+<h3 id="Listening">기본 설정 변경 수신 대기</h3>
+
+<p>사용자가 기본 설정 중 하나를 변경하자마자 이에 대해 알림을 받는 것이 좋은 데에는 몇 가지
+이유가 있습니다. 기본 설정 중 어느 하나에라도 변경이 발생했을 때 콜백을 받으려면,
+{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
+SharedPreference.OnSharedPreferenceChangeListener} 인터페이스를 구현하고
+{@link android.content.SharedPreferences} 객체에 대한 수신기를 등록합니다. 이때 {@link
+android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
+registerOnSharedPreferenceChangeListener()}를 호출하면 됩니다.</p>
+
+<p>이 인터페이스에는 콜백 메서드가 {@link
+android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
+onSharedPreferenceChanged()} 하나뿐이며, 인터페이스를 액티비티의 일부분으로 구현하는 것이
+가장 쉬운 방법일 공산이 큽니다. 예:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity
+ implements OnSharedPreferenceChangeListener {
+ public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
+ ...
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(KEY_PREF_SYNC_CONN)) {
+ Preference connectionPref = findPreference(key);
+ // Set summary to be the user-description for the selected value
+ connectionPref.setSummary(sharedPreferences.getString(key, ""));
+ }
+ }
+}
+</pre>
+
+<p>이 예시에서 메서드는 변경된 설정이 알려진 기본 설정 키에 대한 것인지 여부를 확인합니다. 이것은
+{@link android.preference.PreferenceActivity#findPreference findPreference()}를 호출하여
+변경된 {@link android.preference.Preference} 객체를 가져오는데, 이렇게 해야 항목의 요약을 수정하여
+사용자의 선택에 대한 설명이 되도록 할 수 있습니다. 다시 말해, 설정이 {@link
+android.preference.ListPreference} 또는 다른 다중 선택 설정인 경우, 설정이 변경되어 현재 상태를 표시하도록 하면 {@link
+android.preference.Preference#setSummary setSummary()}를 호출해야 한다는 뜻입니다(예를 들어
+그림 5에 표시된 절전 모드 설정과 같음).</p>
+
+<p class="note"><strong>참고:</strong> Android 디자인 문서의 <a href="{@docRoot}design/patterns/settings.html">설정</a> 관련 내용에서 설명한 바와 같이, 사용자가 기본 설정을 변경할 때마다
+{@link android.preference.ListPreference}의 요약을 업데이트하는 것을 권장합니다. 이렇게 하여 현재 설정을
+나타내는 것입니다.</p>
+
+<p>액티비티에서 적절한 수명 주기 관리를 수행하려면
+{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener}를 등록하고 등록 해제하는 작업은 각각 {@link
+android.app.Activity#onResume} 및 {@link android.app.Activity#onPause} 콜백 중에 수행하는 것을 권장합니다.</p>
+
+<pre>
+&#64;Override
+protected void onResume() {
+ super.onResume();
+ getPreferenceScreen().getSharedPreferences()
+ .registerOnSharedPreferenceChangeListener(this);
+}
+
+&#64;Override
+protected void onPause() {
+ super.onPause();
+ getPreferenceScreen().getSharedPreferences()
+ .unregisterOnSharedPreferenceChangeListener(this);
+}
+</pre>
+
+<p class="caution"><strong>주의:</strong> {@link
+android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
+registerOnSharedPreferenceChangeListener()}를 호출하면
+현재의 경우, 기본 설정 관리자가 수신기에 대한 강력한 참조를 저장하지 않습니다. 반드시 수신기에 대한 강력한
+참조를 저장해야 합니다. 그렇지 않으면 가비지 수집의 대상이 될 가능성이 높습니다. 권장 사항으로는
+수신기를 객체의 인스턴스 데이터 안에 보관하는 것을 추천합니다. 이 객체는
+수신기를 필요로 하는 기간만큼 오래 존재할 것이 확실해야 합니다.</p>
+
+<p>예를 들어 다음 코드에서 발신자는 수신기에 대한 참조를
+보관하지 않습니다. 그 결과 해당 수신기가 가비지 수집의 대상이 되며
+향후 언젠가 알 수 없는 시점에 고장을 일으키게 될 것입니다.</p>
+
+<pre>
+prefs.registerOnSharedPreferenceChangeListener(
+ // Bad! The listener is subject to garbage collection!
+ new SharedPreferences.OnSharedPreferenceChangeListener() {
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ // listener implementation
+ }
+});
+</pre>
+
+<p>대신, 수신기에 대한 참조를 수신기가 필요한 기간만큼 오래 존재할 것이 확실한 객체의
+인스턴스 데이터 필드에 저장하십시오.</p>
+
+<pre>
+SharedPreferences.OnSharedPreferenceChangeListener listener =
+ new SharedPreferences.OnSharedPreferenceChangeListener() {
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ // listener implementation
+ }
+};
+prefs.registerOnSharedPreferenceChangeListener(listener);
+</pre>
+
+<h2 id="NetworkUsage">네트워크 사용량 관리하기</h2>
+
+
+<p>Android 4.0부터 시스템의 설정 애플리케이션을 사용하면 사용자가
+애플리케이션이 전경과 배경에 있는 동안 각각 얼마나 많은 네트워크 데이터를 사용하는지 알아볼 수 있게 되었습니다. 그런 다음
+사용자는 각각의 앱에 대해 배경 데이터 사용을 비활성화할 수 있습니다. 사용자가 여러분의 앱이 배경에서
+데이터에 액세스하는 기능을 비활성화하는 사태를 피하려면 데이터 연결을 효율적으로 사용하고
+사용자가 애플리케이션 설정을 통하여 앱의 데이터 사용량을 미세 조정할 수 있도록 허용해야 합니다.<p>
+
+<p>예를 들어 사용자에게 앱의 데이터 동기화 빈도를 제어하도록 허용할 수 있습니다. 앱이 Wi-Fi에 있을 때에만
+업로드/다운로드를 수행하도록 할지 여부, 앱이 로밍 중에 데이터를 사용하도록 할지 여부 등을 이렇게 조절합니다. 사용자가
+이러한 제어 기능을 사용할 수 있게 되면 시스템 설정에서 설정한 한도에 가까워지고
+있을 때 앱의 데이터 액세스를 비활성화할 가능성이 낮아집니다. 그 대신 앱이 사용하는 데이터 양을
+정밀하게 제어할 수 있기 때문입니다.</p>
+
+<p>일단 필요한 기본 설정을 {@link android.preference.PreferenceActivity}에
+추가하여 앱의 데이터 습관을 제어하도록 했으면, 다음으로 매니페스트 파일에 있는 {@link
+android.content.Intent#ACTION_MANAGE_NETWORK_USAGE}에 대한 인텐트 필터를 추가해야 합니다. 예:</p>
+
+<pre>
+&lt;activity android:name="SettingsActivity" ... >
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+ &lt;category android:name="android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>이 인텐트 필터는 이것이 애플리케이션의 데이터 사용량을 제어하는 액티비티라는
+사실을 시스템에 나타내는 역할을 합니다. 따라서, 사용자가 시스템의 설정 앱에서 여러분의 앱이
+얼마나 많은 데이터를 사용하는지 알아볼 때면 <em>애플리케이션 설정 보기</em> 버튼을 사용할 수 있어
+{@link android.preference.PreferenceActivity}를 시작하게 됩니다. 그러면 사용자는
+앱이 사용할 데이터 양을 미세하게 조정할 수 있습니다.</p>
+
+
+
+
+
+
+
+<h2 id="Custom">사용자 지정 기본 설정 구축하기</h2>
+
+<p>Android 프레임워크에는 다양한 {@link android.preference.Preference} 하위 클래스가 포함되어 있어
+여러 가지 설정 유형에 맞게 UI를 구축할 수 있습니다.
+하지만, 기본 제공 솔루션이 없는 설정이 필요하게 되는 경우도 있습니다. 예를 들어 숫자 선택기 또는
+날짜 선택기 등이 이에 해당됩니다. 그러한 경우에는 사용자 지정 기본 설정을 만들어야 합니다. 이때
+{@link android.preference.Preference} 클래스 또는 다른 하위 클래스 중 하나를 확장하는 방법을 씁니다.</p>
+
+<p>{@link android.preference.Preference} 클래스를 확장하는 경우, 다음과 같이
+몇 가지 중요한 해야 할 일이 있습니다.</p>
+
+<ul>
+ <li>사용자가 설정을 선택하면 나타나는 사용자 인터페이스를 지정합니다.</li>
+ <li>필요에 따라 설정의 값을 저장합니다.</li>
+ <li>{@link android.preference.Preference}가 보이게 되면
+이를 현재(또는 기본) 값으로 초기화합니다.</li>
+ <li>시스템이 요청하는 경우 기본 값을 제공합니다.</li>
+ <li>{@link android.preference.Preference}가 나름의 UI(예: 대화)를 제공하는 경우, 상태를
+저장하고 복원하여 수명 주기 변경을 처리할 수 있도록 합니다(예: 사용자가 화면을 돌리는 경우).</li>
+</ul>
+
+<p>다음 섹션에서는 이와 같은 각각의 작업을 수행하는 방법을 설명합니다.</p>
+
+
+
+<h3 id="CustomSelected">사용자 인터페이스 지정하기</h3>
+
+ <p>{@link android.preference.Preference} 클래스를 직접 확장하는 경우,
+{@link android.preference.Preference#onClick()}을 구현하여 사용자가
+항목을 선택할 때 일어날 동작을 정의해야 합니다. 그러나, 대부분의 사용자 지정 설정은 {@link android.preference.DialogPreference}를 확장하여
+대화를 표시하도록 합니다. 이렇게 하면 절차가 단순해집니다. {@link
+android.preference.DialogPreference}를 확장하는 경우에는 클래스 생성자 중에 반드시 {@link
+android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()}를 호출하여
+대화에 대한 레이아웃을 지정해야 합니다.</p>
+
+ <p>예를 들어 다음은 레이아웃을 선언하는 사용자 지정 {@link
+android.preference.DialogPreference}와 기본
+긍정적 및 부정적 대화 버튼에 대한 텍스트를 지정하는 생성자입니다.</p>
+
+<pre>
+public class NumberPickerPreference extends DialogPreference {
+ public NumberPickerPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ setDialogLayoutResource(R.layout.numberpicker_dialog);
+ setPositiveButtonText(android.R.string.ok);
+ setNegativeButtonText(android.R.string.cancel);
+
+ setDialogIcon(null);
+ }
+ ...
+}
+</pre>
+
+
+
+<h3 id="CustomSave">설정의 값 저장하기</h3>
+
+<p>설정에 대한 값은 언제든 저장할 수 있습니다. {@link
+android.preference.Preference} 클래스의 {@code persist*()} 메서드 중 하나를 호출하기만 하면 됩니다. 예를 들어 설정의 값이 정수인 경우 {@link
+android.preference.Preference#persistInt persistInt()}를, 부울을 저장하려면
+{@link android.preference.Preference#persistBoolean persistBoolean()}을 호출하십시오.</p>
+
+<p class="note"><strong>참고:</strong> 각각의 {@link android.preference.Preference}는 데이터 유형 하나씩만
+저장할 수 있으므로, 사용자 지정
+{@link android.preference.Preference}에서 사용한 데이터 유형에 적절한 {@code persist*()} 메서드를 사용해야 합니다.</p>
+
+<p>설정을 유지하기로 선택하는 시점은 확장하는 지점이 {@link
+android.preference.Preference} 클래스인지에 좌우될 수 있습니다. {@link
+android.preference.DialogPreference}를 확장하면 값을 유지하는 것은 대화가 긍정적인 결과로 인해
+닫히는 경우만으로 국한해야 합니다(사용자가 "확인(OK)" 버튼을 선택하는 경우).</p>
+
+<p>{@link android.preference.DialogPreference}가 닫히면 시스템이 {@link
+android.preference.DialogPreference#onDialogClosed onDialogClosed()} 메서드를 호출합니다. 이 메서드에는
+부울 인수가 포함되어 있어 사용자의 결과가 "긍정적"인지 아닌지를 나타냅니다. 이 값이
+<code>true</code>인 경우, 사용자가 긍정적 버튼을 선택한 것이고 새 값을 저장해야 합니다. 예:
+</p>
+
+<pre>
+&#64;Override
+protected void onDialogClosed(boolean positiveResult) {
+ // When the user selects "OK", persist the new value
+ if (positiveResult) {
+ persistInt(mNewValue);
+ }
+}
+</pre>
+
+<p>이 예시에서 <code>mNewValue</code>는 설정의 현재 값을 보유한 클래스
+구성원입니다. {@link android.preference.Preference#persistInt persistInt()}를 호출하면
+{@link android.content.SharedPreferences} 파일에 대한 값을 저장합니다(이
+{@link android.preference.Preference}에 대하여 XML 파일에 지정된 키를 자동으로 사용합니다).</p>
+
+
+<h3 id="CustomInitialize">현재 값 초기화하기</h3>
+
+<p>시스템이 {@link android.preference.Preference}를 화면에 추가하는 경우, 이는
+{@link android.preference.Preference#onSetInitialValue onSetInitialValue()}를 호출하여
+설정에 유지된 값이 있는지 없는지를 알립니다. 유지된 값이 없는 경우, 이 호출은 기본 값을
+제공합니다.</p>
+
+<p>{@link android.preference.Preference#onSetInitialValue onSetInitialValue()} 메서드는
+부울 값 <code>restorePersistedValue</code>를 전달하여 해당 설정에 대해 이미 어떤 값이 유지되었는지
+아닌지를 나타냅니다. 만일 이것이 <code>true</code>라면, 유지된 값을 검색하되
+{@link
+android.preference.Preference} 클래스의 {@code getPersisted*()} 메서드 중 하나를 호출하는 방법을 써야 합니다. 예를 들어 정수 값이라면 {@link
+android.preference.Preference#getPersistedInt getPersistedInt()}를 사용합니다. 보통은
+유지된 값을 검색하여, UI에 이전에 저장된 값을 반영하여 이를 적절하게 업데이트할 수
+있도록 하는 것이 좋습니다.</p>
+
+<p><code>restorePersistedValue</code>가 <code>false</code>인 경우,
+두 번째 인수로 전달된 기본 값을 사용해야 합니다.</p>
+
+<pre>
+&#64;Override
+protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ if (restorePersistedValue) {
+ // Restore existing state
+ mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
+ } else {
+ // Set default state from the XML attribute
+ mCurrentValue = (Integer) defaultValue;
+ persistInt(mCurrentValue);
+ }
+}
+</pre>
+
+<p>각 {@code getPersisted*()} 메서드는 기본 값을 나타내는 인수를 취하여
+사실은 유지된 값이 전혀 없거나 키 자체가 존재하지 않는 경우 사용하도록 합니다. 위의
+예시에서는 혹시 {@link
+android.preference.Preference#getPersistedInt getPersistedInt()}가 유지된 값을 반환할 수 없는 경우에 사용하도록 기본 값을 나타내는 데 로컬 상수를 사용하였습니다.</p>
+
+<p class="caution"><strong>주의:</strong> {@code getPersisted*()} 메서드에서는
+<code>defaultValue</code>를 기본 값으로 사용하면 <strong>안 됩니다</strong>. 이것의 값은
+<code>restorePersistedValue</code>가 <code>true</code>이면 항상 null이기 때문입니다.</p>
+
+
+<h3 id="CustomDefault">기본 값 제공하기</h3>
+
+<p>{@link android.preference.Preference} 클래스의 인스턴스가 기본 값을 나타내는 경우
+({@code android:defaultValue} 속성으로), 시스템은
+값을 검색하기 위해 객체를 인스턴트화할 때 {@link android.preference.Preference#onGetDefaultValue
+onGetDefaultValue()}를 호출합니다. 이 메서드를 구현해야
+시스템이 {@link
+android.content.SharedPreferences}에 있는 기본 값을 저장할 수 있습니다. 예:</p>
+
+<pre>
+&#64;Override
+protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getInteger(index, DEFAULT_VALUE);
+}
+</pre>
+
+<p>이 메서드 인수가 여러분에게 필요한 모든 것을 제공합니다. 즉 속성 배열과
+{@code android:defaultValue}의 위치로, 이는 반드시 검색해야 합니다. 이 메서드를
+반드시 구현하여 속성에서 기본 값을 추출해야만 하는 이유는 값이 정의되지 않은 경우, 속성에 대한
+로컬 기본 값을 꼭 지정해야 하기 때문입니다.</p>
+
+
+
+<h3 id="CustomSaveState">기본 설정의 상태 저장 및 복원하기</h3>
+
+<p>레이아웃에서의 {@link android.view.View}와 마찬가지로 {@link android.preference.Preference}
+하위 클래스가 액티비티 또는 프래그먼트가 재시작했을 때
+그 상태를 저장하고 복원하는 역할을 맡습니다(예를 들어 사용자가 화면을 돌리는 경우 등).
+{@link android.preference.Preference} 클래스의 상태를 적절하게 저장하고 복원하려면,
+수명 주기 콜백 메서드 {@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} 및 {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}를 구현해야 합니다.</p>
+
+<p>{@link android.preference.Preference}의 상태를 정의하는 것은
+{@link android.os.Parcelable} 인터페이스를 구현하는 객체입니다. Android 프레임워크는
+그러한 객체를 제공하여 상태 객체를 정의하는 데 일종의 시작 지점으로 사용하도록 하고 있습니다. 즉 {@link
+android.preference.Preference.BaseSavedState} 클래스가 이에 해당됩니다.</p>
+
+<p>{@link android.preference.Preference} 클래스가 자신의 상태를 저장하는 방법을 정의하려면
+{@link android.preference.Preference.BaseSavedState} 클래스를 확장해야 합니다. 아주 약간의 메서드를 재정의하고
+{@link android.preference.Preference.BaseSavedState#CREATOR}
+객체를 정의해야 합니다.</p>
+
+<p>대부분의 앱에서는 다음과 같은 구현을 복사한 다음,
+{@code value}를 처리하는 줄만 변경하면 됩니다. 이는 {@link android.preference.Preference} 하위 클래스가 정수보다는 데이터
+유형을 저장하는 경우 해당됩니다.</p>
+
+<pre>
+private static class SavedState extends BaseSavedState {
+ // Member that holds the setting's value
+ // Change this data type to match the type saved by your Preference
+ int value;
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public SavedState(Parcel source) {
+ super(source);
+ // Get the current preference's value
+ value = source.readInt(); // Change this to read the appropriate data type
+ }
+
+ &#64;Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ // Write the preference's value
+ dest.writeInt(value); // Change this to write the appropriate data type
+ }
+
+ // Standard creator object using an instance of this class
+ public static final Parcelable.Creator&lt;SavedState> CREATOR =
+ new Parcelable.Creator&lt;SavedState>() {
+
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+}
+</pre>
+
+<p>위의 {@link android.preference.Preference.BaseSavedState} 구현을 앱에
+추가하고 나면(주로 {@link android.preference.Preference} 하위 클래스의 하위 클래스로), 이제
+{@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} 및 {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} 메서드를 구현해야 합니다. 이것은
+{@link android.preference.Preference} 하위 클래스를 위한 것입니다.</p>
+
+<p>예:</p>
+
+<pre>
+&#64;Override
+protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ // Check whether this Preference is persistent (continually saved)
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent,
+ // use superclass state
+ return superState;
+ }
+
+ // Create instance of custom BaseSavedState
+ final SavedState myState = new SavedState(superState);
+ // Set the state's value with the class member that holds current
+ // setting value
+ myState.value = mNewValue;
+ return myState;
+}
+
+&#64;Override
+protected void onRestoreInstanceState(Parcelable state) {
+ // Check whether we saved the state in onSaveInstanceState
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save the state, so call superclass
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ // Cast state to custom BaseSavedState and pass to superclass
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+
+ // Set this Preference's widget to reflect the restored state
+ mNumberPicker.setValue(myState.value);
+}
+</pre>
+
diff --git a/docs/html-intl/intl/ko/guide/topics/ui/ui-events.jd b/docs/html-intl/intl/ko/guide/topics/ui/ui-events.jd
new file mode 100644
index 000000000000..b059bd24de48
--- /dev/null
+++ b/docs/html-intl/intl/ko/guide/topics/ui/ui-events.jd
@@ -0,0 +1,291 @@
+page.title=입력 이벤트
+parent.title=사용자 인터페이스
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>이 문서의 내용</h2>
+ <ol>
+ <li><a href="#EventListeners">이벤트 수신기</a></li>
+ <li><a href="#EventHandlers">이벤트 처리기</a></li>
+ <li><a href="#TouchMode">터치 모드</a></li>
+ <li><a href="#HandlingFocus">초점 처리하기</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>Android에는 사용자와 애플리케이션의 상호 작용으로부터 이벤트를 가로채는 방법이 여러 가지 있습니다.
+사용자 인터페이스 내의 이벤트가 관련된 경우, 이러한 방식은 이벤트를 사용자가 상호 작용하는
+특정 보기 객체로부터 캡처하는 것입니다. 이에 필요한 수단은 보기 클래스가 제공합니다.</p>
+
+<p>레이아웃을 작성하는 데 사용하게 되는 여러 가지 보기 클래스 안을 보면 UI 이벤트에 유용해 보이는 공개 콜백
+메서드가 여러 개 있는 것이 눈에 띕니다. 이러한 메서드는 해당 객체에서 각각의 작업이 발생할 때 Android 프레임워크가
+호출하는 것입니다. 예를 들어 보기(예: 버튼)를 하나 터치하면
+해당 객체에서 <code>onTouchEvent()</code> 메서드가 호출됩니다. 그러나 이것을 가로채려면 클래스를 확장하고
+메서드를 재정의해야 합니다. 다만 그런 이벤트를 처리하기 위해 모든 보기 객체를
+다 확장하는 것은 타당성이 없습니다. 이 때문에 보기 클래스에
+일련의 중첩된 인터페이스가 있고 거기에 훨씬 쉽게 정의할 수 있는 콜백에 있습니다. 이와 같은
+인터페이스를 일명 <a href="#EventListeners">이벤트 수신기</a>라고 하는데, 이것이 UI와 사용자 상호 작용을 캡처하는 데 아주 적합합니다.</p>
+
+<p>사용자 상호 작용을 수신 대기하는 데에는 이벤트 수신기를 사용하는 것이 좀 더 보편적이지만, 사용자 지정
+구성 요소를 구축하기 위해 보기 클래스를 확장하고자 하는 상황이 올 수도 있습니다.
+어쩌면 {@link android.widget.Button}
+클래스를 확장하여 무언가 더 복잡한 것을 만들고자 할 수도 있습니다. 이런 경우, 클래스에 대한 기본 이벤트 행동을 클래스
+<a href="#EventHandlers">이벤트 처리기</a>를 사용하여 정의할 수 있습니다.</p>
+
+
+<h2 id="EventListeners">이벤트 수신기</h2>
+
+<p>이벤트 수신기란 {@link android.view.View} 클래스 내에 있는 일종의 인터페이스로, 이 안에 하나의
+콜백 메서드가 들어있습니다. 이러한 메서드는 수신기가 등록된 보기가 UI 안의 항목과 사용자의 상호 작용으로 인하여 트리거되었을 때
+Android 프레임워크가 호출하는 것입니다.</p>
+
+<p>이벤트 수신기 인터페이스에 포함된 콜백 메서드는 다음과 같습니다.</p>
+
+<dl>
+ <dt><code>onClick()</code></dt>
+ <dd>{@link android.view.View.OnClickListener}에서 온 것입니다.
+이것이 호출되는 것은 사용자가 항목을 터치하거나
+(터치 모드에 있을 때), 탐색 키 또는 트랙볼을 사용하여 해당 항목에 초점을 맞추고 있으면서
+적절한 "엔터" 키를 누르거나 트랙볼을 꾹 누를 때입니다.</dd>
+ <dt><code>onLongClick()</code></dt>
+ <dd>{@link android.view.View.OnLongClickListener}에서 온 것입니다.
+이것이 호출되는 것은 사용자가 항목을 길게 누르거나(터치 모드에 있을 때),
+탐색 키 또는 트랙볼을 사용하여 해당 항목에 초점을 맞추고 있으면서
+적절한 "엔터" 키를 누르거나 트랙볼을 꾹 누를 때입니다(일 초간).</dd>
+ <dt><code>onFocusChange()</code></dt>
+ <dd>{@link android.view.View.OnFocusChangeListener}에서 온 것입니다.
+이것이 호출되는 것은 사용자가 탐색 키 또는 트랙볼을 사용하여 항목 쪽으로 이동하거나 항목에서 멀어질 때입니다.</dd>
+ <dt><code>onKey()</code></dt>
+ <dd>{@link android.view.View.OnKeyListener}에서 온 것입니다.
+이것이 호출되는 것은 사용자가 항목에 초점을 맞추고 있으면서 기기에 있는 하드웨어 키를 누르거나 키에서 손을 떼는 경우입니다.</dd>
+ <dt><code>onTouch()</code></dt>
+ <dd>{@link android.view.View.OnTouchListener}에서 온 것입니다.
+이것이 호출되는 것은 사용자가 터치 이벤트로서의 자격을 만족하는 작업을 수행하는 경우로, 여기에
+누르기, 손 떼기와 화면에서 이루어지는 모든 움직임 동작(항목의 경계 내에서)이 포함됩니다.</dd>
+ <dt><code>onCreateContextMenu()</code></dt>
+ <dd>{@link android.view.View.OnCreateContextMenuListener}에서 온 것입니다.
+이것을 호출하는 것은 컨텍스트 메뉴가 구축되는 중일 때입니다(정체된 "롱 클릭"의 결과로).
+<a href="{@docRoot}guide/topics/ui/menus.html#context-menu">메뉴</a>
+ 개발자 가이드에 있는 컨텍스트 메뉴 관련 논의를 참조하십시오.</dd>
+</dl>
+
+<p>이러한 메서드는 각자의 인터페이스 안에 거주하는 유일한 주민입니다. 이러한 메서드 중 하나를
+정의하고 이벤트를 처리하려면 액티비티 내의 중첩된 인터페이스를 구현하거나 익명의 클래스로 정의하면 됩니다.
+그런 다음 구현의 인스턴스 하나를
+각각의 <code>View.set...Listener()</code> 메서드에 전달하십시오 (예:
+<code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code>를
+호출한 다음 이를 {@link android.view.View.OnClickListener OnClickListener}의 구현에 전달합니다).</p>
+
+<p>아래의 예시는 버튼에 대하여 온-클릭 수신기를 등록하는 방법을 나타낸 것입니다. </p>
+
+<pre>
+// Create an anonymous implementation of OnClickListener
+private OnClickListener mCorkyListener = new OnClickListener() {
+ public void onClick(View v) {
+ // do something when the button is clicked
+ }
+};
+
+protected void onCreate(Bundle savedValues) {
+ ...
+ // Capture our button from layout
+ Button button = (Button)findViewById(R.id.corky);
+ // Register the onClick listener with the implementation above
+ button.setOnClickListener(mCorkyListener);
+ ...
+}
+</pre>
+
+<p>OnClickListener를 액티비티의 일부로 구현하는 것이 더 편리할 수도 있습니다.
+이렇게 하면 클래스 부하와 객체 할당이 추가되는 것을 피할 수 있습니다. 예:</p>
+<pre>
+public class ExampleActivity extends Activity implements OnClickListener {
+ protected void onCreate(Bundle savedValues) {
+ ...
+ Button button = (Button)findViewById(R.id.corky);
+ button.setOnClickListener(this);
+ }
+
+ // Implement the OnClickListener callback
+ public void onClick(View v) {
+ // do something when the button is clicked
+ }
+ ...
+}
+</pre>
+
+<p>위의 예시에서 <code>onClick()</code> 콜백에는
+반환 값이 없지만 다른 이벤트 수신기 메서드 중에는 부울 값을 반환해야만 하는 것도 있다는 점을 유의하십시오. 그 이유는 이벤트에 따라
+다릅니다. 이런 필수 사항이 적용되는 몇몇 메서드의 경우, 이유는 다음과 같습니다.</p>
+<ul>
+ <li><code>{@link android.view.View.OnLongClickListener#onLongClick(View) onLongClick()}</code> -
+이것은 부울 값을 반환하여 이벤트를 완전히 사용하였으며 더 이상 이를 담지 않아도 되는지 여부를 나타냅니다.
+다시 말해, <em>참</em>을 반환하면 이벤트를 처리했으며 여기에서 중단해야 한다는 것을 의미하며
+<em>거짓</em>을 반환하면 이벤트가 아직 미처리 상태이며/거나 이 이벤트를 다른
+온-클릭 수신기로 계속 진행해야 할지 나타내는 것입니다.</li>
+ <li><code>{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent) onKey()}</code> -
+이것은 부울 값을 반환하여 이벤트를 완전히 사용하였으며 더 이상 이를 담지 않아도 되는지 여부를 나타냅니다.
+ 다시 말해, <em>참</em>을 반환하면 이벤트를 처리했으며 여기에서 중단해야 한다는 것을 의미하며
+<em>거짓</em>을 반환하면 이벤트가 아직 미처리 상태이며/거나 이 이벤트를 다른
+온-키 수신기로 계속 진행해야 할지 나타내는 것입니다.</li>
+ <li><code>{@link android.view.View.OnTouchListener#onTouch(View,MotionEvent) onTouch()}</code> -
+이것은 부울 값을 반환하여 수신기가 이 이벤트를 사용하는지 아닌지를 나타냅니다. 여기서 중요한 점은
+이 이벤트에는 서로 연달아 발생하는 여러 개의 작업이 있을 수 있다는 것입니다. 그러므로 '아래로' 작업 이벤트를 수신했을 때 <em>거짓</em>을 반환하면,
+해당 이벤트를 사용하지 않았으며 이 이벤트로부터 이어지는 이후의 작업에
+흥미가 없음을 나타내는 것이 됩니다. 따라서 이 이벤트 내의 다른 모든 작업에 대해
+호출되지 않습니다(예: 손가락 동작 또는 최종적인 '위로' 작업 이벤트 등).</li>
+</ul>
+
+<p>하드웨어 키 이벤트는 항상 현재 초점의 중심에 있는 보기로 전달된다는 점을 명심하십시오. 이들은 보기 계층의 맨 위에서 시작하여
+아래 방향으로 발송되어 적절한 목적지에 도달할 때까지 계속합니다. 보기(또는 보기의 하위)에
+현재 초점이 맞춰져 있으면, 이벤트가 <code>{@link android.view.View#dispatchKeyEvent(KeyEvent)
+dispatchKeyEvent()}</code> 메서드를 통과하여 이동하는 것을 확인할 수 있습니다. 보기를 통해 키 이벤트를 캡처하는 대신, 액티비티 내부의 모든 이벤트를 <code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code>및
+
+<code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code>을 사용하여 수신할 수도 있습니다.</p>
+
+<p>또한, 애플리케이션에 대한 텍스트 입력의 경우 대다수의 기기에는 소프트웨어 입력 메서드만 있다는 사실을
+명심하십시오. 그러한 메서드는 반드시 키 기반이 아니어도 됩니다. 음성 입력, 손글씨 등을 사용하는 것도 있습니다. 입력
+메서드가 키보드 같은 인터페이스를 표시하더라도 일반적으로
+<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> 이벤트군을 트리거하지는 <strong>않습니다</strong>. 특정 키 누름을
+제어해야만 하는 UI는 절대 구축하면 안 됩니다. 이렇게 하면 애플리케이션이 하드웨어 키보드가 있는
+기기에만 한정됩니다. 특히, 사용자가 리턴 키를 누르면 입력의 유효성을 검사하는 데 이와 같은 메서드에
+의존해서는 안 됩니다. 대신, {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE}과 같은 작업을 사용하여 애플리케이션이 반응할 것으로 기대되는 방식에 해당되는
+입력 메서드를 신호하여 의미 있는 방식으로 UI를 변경할 수 있게 하는 것이 좋습니다. 소프트웨어 입력 메서드가
+어떻게 작동할지 임의로 추정하지 마시고, 이미 서식 지정된 텍스트를 애플리케이션에 제공해줄 것이라 믿으면 됩니다.</p>
+
+<p class="note"><strong>참고:</strong> Androids는 우선 이벤트 처리기부터 호출하고, 그 다음에 클래스 정의로부터 가져온
+적절한 기본 처리기를 두 번째로 호출합니다. 따라서, 이와 같은 이벤트 수신기에서 <em>참</em>을 반환하면 이벤트가
+다른 이벤트 수신기로 전파되는 것을 중지시킬 뿐만 아니라 보기에 있는
+기본 이벤트 처리기로의 콜백도 차단하게 됩니다. 따라서 <em>참</em>을 반환하는 경우 해당 이벤트를 종료하고 싶은 것인지 확신해야 합니다.</p>
+
+
+<h2 id="EventHandlers">이벤트 처리기</h2>
+
+<p>보기에서 사용자 지정 구성 요소를 구축하는 경우, 기본 이벤트 처리기로 사용될 콜백 메서드를
+여러 개 정의할 수 있게 됩니다.
+<a href="{@docRoot}guide/topics/ui/custom-components.html">사용자 지정
+구성 요소</a>에 대한 문서를 보면 이벤트 처리에 사용되는 몇 가지 보편적인 콜백을 확인할 수 있습니다.
+다음은 그 몇 가지 예입니다.</p>
+<ul>
+ <li><code>{@link android.view.View#onKeyDown}</code> - 새로운 키 이벤트가 발생하면 호출합니다.</li>
+ <li><code>{@link android.view.View#onKeyUp}</code> - 새로운 키 '위로' 이벤트가 발생하면 호출합니다.</li>
+ <li><code>{@link android.view.View#onTrackballEvent}</code> - 트랙볼 동작 이벤트가 발생하면 호출합니다.</li>
+ <li><code>{@link android.view.View#onTouchEvent}</code> - 터치 스크린 동작 이벤트가 발생하면 호출합니다.</li>
+ <li><code>{@link android.view.View#onFocusChanged}</code> - 보기가 초점을 취하거나 이를 잃으면 호출합니다.</li>
+</ul>
+<p>개발자 여러분이 알아두어야 하는 다른 메서드가 몇 가지 더 있습니다. 이들은 보기 클래스의 일부분이 아니지만,
+이벤트를 처리할 수 있는 방식에 직접적으로 영향을 미칠 수 있는 것들입니다. 그러니, 레이아웃 안에서 좀 더 복잡한 이벤트를 관리하는 경우,
+이와 같은 다른 메서드도 고려하십시오.</p>
+<ul>
+ <li><code>{@link android.app.Activity#dispatchTouchEvent(MotionEvent)
+ Activity.dispatchTouchEvent(MotionEvent)}</code> - 이것을 사용하면 {@link
+ android.app.Activity}로 하여금 모든 터치 이벤트가 창으로 발송되기 전에 이들을 가로채도록 할 수 있습니다.</li>
+ <li><code>{@link android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)
+ ViewGroup.onInterceptTouchEvent(MotionEvent)}</code> - 이것을 사용하면 {@link
+ android.view.ViewGroup}으로 하여금 이벤트가 하위 보기로 발송되는 것을 지켜보도록 할 수 있습니다.</li>
+ <li><code>{@link android.view.ViewParent#requestDisallowInterceptTouchEvent(boolean)
+ ViewParent.requestDisallowInterceptTouchEvent(boolean)}</code> - 이것을
+호출하는 것은 상위 보기에 <code>{@link
+ android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)}</code>가 있는 터치 이벤트를 가로채면 안 된다고 나타낼 때입니다.</li>
+</ul>
+
+<h2 id="TouchMode">터치 모드</h2>
+<p>
+사용자가 방향 키 또는 트랙볼을 사용하여 사용자 인터페이스를 탐색하고 있는 경우,
+조치 가능한 항목(예: 버튼)에 초점을 맞춰 어느 것이 입력을 허용할지 사용자가
+볼 수 있도록 해야 합니다. 하지만 기기에 터치 기능이 있고 사용자가
+인터페이스를 터치하여 인터페이스와의 상호 작용을 시작하는 경우라면, 더 이상 항목을 강조 표시하거나
+특정 보기에 초점을 맞추지 않아도 됩니다. 따라서 "터치 모드"라고 불리는 상호 작용에 대한
+모드가 따로 있습니다.
+</p>
+<p>
+터치 기능이 있는 기기의 경우, 사용자가 화면을 터치하면 기기가 터치 모드에
+진입하게 됩니다. 이 시점부터는
+{@link android.view.View#isFocusableInTouchMode}가 참인 보기에만 초점을 맞출 수 있습니다. 예를 들어 텍스트 편집 위젯이 이에 해당됩니다.
+버튼처럼 터치할 수 있는 다른 보기의 경우 터치해도 주의를 끌 수 없으며 이를 누르면 그저
+온-클릭 수신기를 실행시키기만 합니다.
+</p>
+<p>
+사용자가 방향 키를 누르거나 트랙볼로 스크롤 동작을 할 때마다 기기가
+터치 모드를 종료하고 초점을 맞출 보기를 찾습니다. 이제 사용자는 사용자 인터페이스와
+상호 작용을 재개해도 되며, 화면을 터치하지 않아도 됩니다.
+</p>
+<p>
+터치 모드 상태는 시스템 전체를 통틀어 유지됩니다(모든 창과 액티비티 포함).
+현재 상태를 쿼리하려면
+{@link android.view.View#isInTouchMode}를 호출하여 기기가 현재 터치 모드에 있는지 확인하면 됩니다.
+</p>
+
+
+<h2 id="HandlingFocus">초점 처리하기</h2>
+
+<p>프레임워크가 사용자 입력에 응답하여 일상적인 초점 이동을 처리합니다.
+여기에는 보기가 제거되거나 숨겨지는 것, 또는 새 보기를 사용할 수 있게 됨에 따라
+초점을 변경하는 것이 포함됩니다. 보기는 초점을 취하고자 하는 의향을
+<code>{@link android.view.View#isFocusable()}</code> 메서드를 통해 나타냅니다. 보기가 초점을 취할 수 있는지 여부를 변경하려면
+<code>{@link android.view.View#setFocusable(boolean) setFocusable()}</code>을 호출합니다. 터치 모드에 있는 경우,
+어느 보기가 <code>{@link android.view.View#isFocusableInTouchMode()}</code>로 초점을 취하는 것을 허용하는지 여부를 쿼리할 수 있습니다.
+이것은 <code>{@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}</code>로 변경하면 됩니다.
+</p>
+
+<p>초점 이동은 주어진 방향에서 가장 가까운 이웃을 찾아내는 알고리즘을 기반으로
+합니다. 드문 일이지만 기본 알고리즘이 개발자가 의도한 행동과 일치하지 않는
+경우도 있습니다. 이러한 상황이라면, 레이아웃 파일에서 다음과 같은 XML 속성을
+사용하여 명시적 재정의를 제공하면 됩니다.
+<var>nextFocusDown</var>, <var>nextFocusLeft</var>, <var>nextFocusRight</var>, 및
+<var>nextFocusUp</var>입니다. 이와 같은 속성 중 한 가지를 초점이 <em>떠나고</em> 있는 보기에
+추가합니다. 속성의 값을 초점을
+<em>맞춰야 할</em> 보기의 ID가 되도록 정의합니다. 예:</p>
+<pre>
+&lt;LinearLayout
+ android:orientation="vertical"
+ ... >
+ &lt;Button android:id="@+id/top"
+ android:nextFocusUp="@+id/bottom"
+ ... />
+ &lt;Button android:id="@+id/bottom"
+ android:nextFocusDown="@+id/top"
+ ... />
+&lt;/LinearLayout>
+</pre>
+
+<p>보통은 이런 수직 레이아웃에서 첫 버튼부터 위로 이동하면 아무 데도 갈 수 없고,
+두 번째 버튼에서 아래로 이동해도 마찬가지입니다. 이제 맨 위 버튼이 맨 아래 버튼을 다음과 같이
+정의했습니다. <var>nextFocusUp</var> (반대쪽도 마찬가지) 따라서 이동 초점은 위에서 아래로 갔다가
+아래에서 위로 순환하게 됩니다.</p>
+
+<p>보기를 UI에서 초점을 맞출 수 있는 것으로 선언하고자 하는 경우(일반적으로는 그렇지 않음),
+보기에 레이아웃 선언에서 <code>android:focusable</code> XML 속성을 추가합니다.
+이 값을 <var>참</var>으로 설정합니다. 터치 모드에 있을 때에도 보기를 초점을 맞출 수 있는 것으로
+선언할 수 있습니다. <code>android:focusableInTouchMode</code>를 사용하면 됩니다.</p>
+<p>특정 보기에 초점을 맞추기를 요청하려면, <code>{@link android.view.View#requestFocus()}</code>를 호출하십시오.</p>
+<p>초점 이벤트를 수신 대기하려면(어떤 보기에 초점이 맞춰지거나 이를 잃는 경우 알림을 받으려면),
+<code>{@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}</code>를 사용하면 됩니다.
+이는 위의 <a href="#EventListeners">이벤트 수신기</a> 섹션에서 이야기한 바와 같습니다.</p>
+
+
+
+<!--
+<h2 is="EventCycle">Event Cycle</h2>
+ <p>The basic cycle of a View is as follows:</p>
+ <ol>
+ <li>An event comes in and is dispatched to the appropriate View. The View
+ handles the event and notifies any listeners.</li>
+ <li>If, in the course of processing the event, the View's bounds may need
+ to be changed, the View will call {@link android.view.View#requestLayout()}.</li>
+ <li>Similarly, if in the course of processing the event the View's appearance
+ may need to be changed, the View will call {@link android.view.View#invalidate()}.</li>
+ <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called,
+ the framework will take care of measuring, laying out, and drawing the tree
+ as appropriate.</li>
+ </ol>
+
+ <p class="note"><strong>Note:</strong> The entire View tree is single threaded. You must always be on
+ the UI thread when calling any method on any View.
+ If you are doing work on other threads and want to update the state of a View
+ from that thread, you should use a {@link android.os.Handler}.
+ </p>
+-->
diff --git a/docs/html-intl/intl/ko/index.jd b/docs/html-intl/intl/ko/index.jd
index d95d6985a0aa..01c85873c6c6 100644
--- a/docs/html-intl/intl/ko/index.jd
+++ b/docs/html-intl/intl/ko/index.jd
@@ -5,42 +5,81 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3
@jd:body
-<!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel">
-</div> -->
-<section class="dac-hero-carousel">
+<script>
+ $(document).ready(function() {
+ if (useUpdatedTemplates) {
+ $("#useUpdatedTemplates").css("display","block");
+ } else {
+ $("#useOldTemplates").css("display","block");
+ }
+ })
+</script>
-<!-- <article class="dac-expand dac-hero dac-invert active" style="background-color: rgb(38, 50, 56);"> -->
-<article class="dac-expand dac-hero dac-invert dac-darken mprev active" style="background-color: #75d1ff;">
-<a href="/preview/index.html">
+<section class="dac-expand dac-hero dac-invert" style="background-color:#455A64">
<div class="wrap" style="max-width:1100px;margin-top:0">
- <div class="cols dac-hero-content">
- <div class="col-8of16 col-push-6of16 dac-hero-figure mprev">
- </div>
- <div class="col-8of16 col-pull-7of16">
- <div class="dac-hero-tag"></div>
-
- <h1 class="dac-hero-title" style="white-space:nowrap;">Android 6.0 Marshmallow</h1>
- <p class="dac-hero-description">Android의 다음 버전을 만나볼 준비가
- 되셨습니까? 여러분의 앱을 Nexus 5, 6, 9 및 Player에서 테스트해보십시오. </p>
-
- <a class="dac-hero-cta" href="{@docRoot}preview/index.html">
+ <div class="col-7of16 col-push-9of16" style="padding-left:2em;">
+ <a href="{@docRoot}preview/index.html">
+ <h1 class="dac-hero-title">Android N Developer Preview</h1>
+ <p class="dac-hero-description">
+ Get ready for the next version of Android!
+ <strong>Test your apps</strong> on Nexus and other devices. Support new system
+ behaviors to <strong>save power and memory</strong>.
+ Extend your apps with <strong>multi-window UI</strong>,
+ <strong>direct reply notifications</strong> and more.
+ </p>
+ <a class="dac-hero-cta" href="/preview/index.html">
<span class="dac-sprite dac-auto-chevron"></span>
- 지금 시작하세요!
- </a><br>
- <a class="dac-hero-cta" href="{@docRoot}preview/support.html">
+ Learn more
+ </a><!--<br>
+ <a class="dac-hero-cta" href="/preview/support.html">
<span class="dac-sprite dac-auto-chevron"></span>
- Developer Preview 3 (final SDK)</a>
- </div>
+ Update to Developer Preview (final SDK)
+ </a><br>-->
+ </a>
+ </div>
+ <div class="col-9of16 col-pull-7of16 dac-hero-figure" style="margin-top:0em;padding-right:1.5em;">
+ <a href="{@docRoot}preview/index.html">
+ <img style="" class="dac-hero-image" src="/images/home/n-preview-hero.png"
+ srcset="/images/home/n-preview-hero.png 1x,
+ /images/home/n-preview-hero_2x.png 2x">
+ </a>
</div>
</div>
-</a>
-</article></section>
+</section>
-<div class="actions-bar dac-expand dac-invert">
+<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand">
<div class="wrap dac-offset-parent">
<a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps">
<i class="dac-sprite dac-arrow-down-gray"></i>
</a>
+ <ul class="dac-actions">
+ <li class="dac-action">
+ <a class="dac-action-link" href="{@docRoot}sdk/index.html">
+ <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
+ Get the SDK
+ </a>
+ </li>
+ <li class="dac-action">
+ <a class="dac-action-link" href="{@docRoot}samples/index.html">
+ <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
+ Browse sample code
+ </a>
+ </li>
+ <li class="dac-action">
+ <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html">
+ <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
+ Watch stories
+ </a>
+ </li>
+ </ul>
+ </div><!-- end .wrap -->
+</div><!-- end .dac-actions -->
+
+<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert">
+ <div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
<div class="actions">
<div><a href="{@docRoot}sdk/index.html">
<span class="dac-sprite dac-auto-chevron-large"></span>
@@ -50,17 +89,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3
<span class="dac-sprite dac-auto-chevron-large"></span>
Browse Samples
</a></div>
- <div><a href="//www.youtube.com/user/androiddevelopers">
+ <div><a href="{@docRoot}distribute/stories/index.html">
<span class="dac-sprite dac-auto-chevron-large"></span>
- Watch Videos
+ Watch Stories
</a></div>
</div><!-- end .actions -->
</div><!-- end .wrap -->
-</div><!-- end .actions-bar -->
-
-
+</div>
-<section class="dac-section dac-section-light" id="build-apps"><div class="wrap">
+<section class="dac-section dac-light" id="build-apps"><div class="wrap">
<h1 class="dac-section-title">Build Beautiful Apps</h1>
<div class="dac-section-subtitle">
Resources to get you started with designing and developing for Android.
diff --git a/docs/html-intl/intl/ko/preview/api-overview.jd b/docs/html-intl/intl/ko/preview/api-overview.jd
deleted file mode 100644
index aac9a44924e0..000000000000
--- a/docs/html-intl/intl/ko/preview/api-overview.jd
+++ /dev/null
@@ -1,521 +0,0 @@
-page.title=API 개요
-page.keywords=미리 보기, SDK, 호환성
-page.tags=previewresources, androidm
-sdk.platform.apiLevel=22-mnc
-page.image=images/cards/card-api-overview_16-9_2x.png
-@jd:body
-
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>이 문서의 내용
- <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
- <span class="more">더 보기</span>
- <span class="less" style="display:none">숨기기</span></a></h2>
-
-<ol id="toc44" class="hide-nested">
- <li><a href="#app-linking">앱 연결</a></li>
- <li><a href="#backup">앱용 자동 백업</a></li>
- <li><a href="#authentication">인증</a>
- <ol>
- <li><a href="#fingerprint-authentication">지문 인증</a></li>
- <li><a href="#confirm-credential">확인 자격 증명</a></li>
- </ol>
- </li>
- <li><a href="#direct-share">직접 공유</a></li>
- <li><a href="#voice-interactions">음성 상호작용</a></li>
- <li><a href="#assist">지원 API</a></li>
- <li><a href="#notifications">알림</a></li>
- <li><a href="#bluetooth-stylus">블루투스 스타일러스 지원</a></li>
- <li><a href="#ble-scanning">블루투스 저전력 스캔 개선</a></li>
- <li><a href="#hotspot">핫스팟 2.0 릴리스 1 지원</a></li>
- <li><a href="#4K-display">4K 디스플레이 모드</a></li>
- <li><a href="#behavior-themeable-colorstatelists">테마 지정 가능 ColorStateLists</a></li>
- <li><a href="#audio">오디오 기능</a></li>
- <li><a href="#video">비디오 기능</a></li>
- <li><a href="#camera">카메라 기능</a>
- <ol>
- <li><a href="#flashlight">Flashlight API</a></li>
- <li><a href="#reprocessing">카메라 재처리</a></li>
- </ol>
- </li>
- <li><a href="#afw">Android for Work 기능</a></li>
-</ol>
-
-<h2>API 차이점</h2>
-<ol>
-<li><a href="{@docRoot}preview/download.html">M 미리 보기에 대한 API 레벨 22 &raquo;</a> </li>
-</ol>
-
-</div>
-</div>
-
-<p>M 개발자 미리 보기에서는 다가오는 Android 플랫폼 릴리스를 미리 볼 수 있도록 하였습니다. 이 릴리스는 사용자와 앱 개발자를 위한 여러 가지 새 기능을 제공합니다.
-
- 이 문서에서는 가장 중요한 API를 몇 가지 소개합니다.</p>
-
-<p>M 개발자 미리 보기는 <strong>개발자 얼리 어답터</strong>와 <strong>테스터</strong>를 위해 마련된 것입니다.
- Android 프레임워크가 나아갈 방향에 영향을 미치는 데 관심이 있으시다면, <a href="{@docRoot}preview/setup-sdk.html">M 개발자 미리 보기를 시도해 보시고</a> 피드백을 보내주세요!
-
-
-</p>
-
-<p class="caution"><strong>주의:</strong> M 개발자 미리 보기를 사용하는 앱을 Google Play 스토어에 게시하지 마세요.
-</p>
-
-<p class="note"><strong>참고:</strong> 이 문서에서 종종 언급하는 클래스와 메서드 중에는 아직 <a href="{@docRoot}">developer.android.com</a>에서 참조 자료로 이용할 수 없는 것도 있습니다.
- 이와 같은 API 요소는 이 문서에서 {@code code style}로 형식 지정되어 있습니다(하이퍼링크 없이).
- 이러한 요소에 대한 임시 API 관련 문서가 필요한 경우, <a href="{@docRoot}preview/download.html#docs">미리 보기 참조</a>를 다운로드하세요.
-</p>
-
-<h3>중요한 동작 변경</h3>
-
-<p>이전에 Android용 앱을 게시한 적이 있는 경우, 플랫폼 변경으로 인해 앱이 영향받을 수 있다는 점을 유의하세요.
-</p>
-
-<p>완전한 정보는 <a href="behavior-changes.html">동작 변경</a>을 참조하세요.</p>
-
-<h2 id="app-linking">앱 연결</h2>
-<p>이 미리 보기는 더욱 강력한 앱 연결을 제공하여 Android의 인텐트 시스템을 한층 강화합니다. 이 기능을 사용하면 앱을 본인이 소유한 웹 도메인과 연관시킬 수 있습니다.
- 플랫폼은 이 연관 관계를 근거로 특정한 웹 링크를 처리하는 데 사용할 기본 앱을 결정할 수 있고 사용자에게 앱을 선택하라는 메시지를 건너뛸 수 있습니다. 이 기능을 구현하는 방법을 알아보려면 <a href="{@docRoot}preview/features/app-linking.html">앱 연결</a>을 참조하세요.
-
-
-
-
-<h2 id="backup">앱용 자동 백업</h2>
-<p>시스템에서 이제 앱에 대한 완전한 데이터 백업과 복원을 자동으로 수행합니다. 이 동작은 앱 대상 지정 M 미리 보기에 대한 기본으로 활성화되며, 추가 코드를 전혀 추가하지 않아도 됩니다.
- 사용자가 Google 계정을 삭제하면 계정의 백업 데이터도 함께 삭제됩니다.
- 이 기능의 작동 원리와 파일 시스템에서 백업 내용 구성하는 방법에 대해 알아보려면 <a href="{@docRoot}preview/backup/index.html">앱용 자동 백업</a>을 참조하세요.
-
-</p>
-
-<h2 id="authentication">인증</h2>
-<p>이 미리 보기에서는 사용자를 인증할 때 지원되는 기기에서 지문 스캔을 사용하도록 해주는 새로운 API를 제공합니다. 또한 기기 잠금 해제 메커니즘(예: 화면 잠금 비밀번호)을 사용해 사용자의 마지막 인증 시간을 확인할 수도 있습니다.
-
- 이러한 API는 <a href="{@docRoot}training/articles/keystore.html">Android Keystore 시스템</a>과 함께 사용하세요.
-</p>
-
-<h3 id="fingerprint-authentication">지문 인증</h3>
-
-<p>지문 스캔을 통해 사용자를 인증하려면 새로운 {@code android.hardware.fingerprint.FingerprintManager} 클래스의 인스턴스를 가져와 {@code FingerprintManager.authenticate()} 메서드를 호출하세요.
-
- 앱이 지문 센서가 있는 호환되는 기기에서 실행되고 있어야 합니다.
- 지문 인증 흐름에 대한 사용자 인터페이스를 앱에 구현해야 하며, UI에 표준 Android 지문 아이콘을 사용해야 합니다. 이 Android 지문 아이콘({@code c_fp_40px.png})은 <a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">샘플 앱</a>에 포함되어 있습니다. 지문 인증을 사용하는 앱을 여러 개 개발하는 경우, 각 앱이 사용자의 지문을 따로따로 인증해야 한다는 사실을 명심하세요.
-
-
-
-
-</p>
-
-<p>앱에서 이 기능을 사용하려면 우선 매니페스트에 {@code USE_FINGERPRINT} 권한을 추가해야 합니다.
-</p>
-
-<pre>
-&lt;uses-permission
- android:name="android.permission.USE_FINGERPRINT" /&gt;
-</pre>
-
-<img src="{@docRoot}preview/images/fingerprint-screen.png" srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
-
-<p>지문 인증의 앱 구현을 확인하려면, <a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">지문 대화 샘플</a>을 참조하세요.
-
-</p>
-
-<p>이 기능을 테스트하는 경우, 다음 단계를 따르면 됩니다.</p>
-<ol>
-<li>아직 Android SDK 도구 수정 버전 24.3을 설치합니다(설치하지 않은 경우).</li>
-<li>에뮬레이터에 새 지문을 등록하려면 <strong>설정 &gt; 보안 &gt; 지문</strong>으로 이동한 다음, 등록 지침을 따르면 됩니다.
-</li>
-<li>에뮬레이터를 사용하여 지문 터치 이벤트를 에뮬레이트하되 다음 명령을 사용하세요.
- 잠금 화면이나 앱에서 지문 터치 이벤트를 에뮬레이트할 때에도 같은 명령을 사용합니다.
-
-<pre class="no-prettyprint">
-adb -e emu finger touch &lt;finger_id&gt;
-</pre>
-<p>Windows에서는 {@code telnet 127.0.0.1 &lt;emulator-id&gt;}에 뒤이어 {@code finger touch &lt;finger_id&gt;}를 실행해야 할 수도 있습니다.
-
-</p>
-</li>
-</ol>
-
-<h3 id="confirm-credential">확인 자격 증명</h3>
-<p>앱에서 사용자를 인증할 때 해당 사용자가 기기를 마지막으로 잠금 해제한 시간을 근거로 할 수 있습니다. 이 기능을 사용하면 사용자가 앱에 따라 각기 다른 비밀번호를 기억할 필요가 없어지고, 개발자는 자신만의 인증 사용자 인터페이스를 구현하지 않아도 됩니다.
-
- 앱에서 이 기능을 사용하려면 사용자 인증에 대한 공개 또는 비밀 키 구현과 함께 사용해야 합니다.
-</p>
-
-<p>사용자를 성공적으로 인증한 다음 같은 키를 재사용하기 위한 시간 초과 기간을 설정하려면, 새로운 {@code android.security.keystore.KeyGenParameterSpec.setUserAuthenticationValidityDurationSeconds()} 메서드를 호출하세요. {@link javax.crypto.KeyGenerator} 또는 {@link java.security.KeyPairGenerator}를 설정할 때 사용하면 됩니다.
-
-
-
- 현재 이 기능은 대칭형 암호화 작동에 맞게 작동합니다.
-</p>
-
-<p>재인증 대화창을 과도하게 표시하는 것을 삼가세요. 우선 앱에서 암호화 객체 사용을 시도해보고, 제한 시간이 만료되면 {@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()} 메서드를 사용해 앱 내에서 해당 사용자를 재인증하면 됩니다.
-
-
-
-</p>
-
-<p>이 기능의 앱 구현을 확인하려면, <a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">확인 자격 증명 샘플</a>를 참조하세요.
-
-</p>
-
-<h2 id="direct-share">직접 공유</h2>
-
-<img src="{@docRoot}preview/images/direct-share-screen.png" srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x" style="float:right; margin:0 0 20px 30px" width="312" height="329" />
-
-<p>이 미리 보기에서는 사용자가 공유 기능을 간편하고 신속하게 이용할 수 있도록 해주는 API를 제공합니다. 이제 앱에서 특정 액티비티를 시작하는 <em>직접 공유 대상</em>을 정의할 수 있습니다. 이와 같은 직접 공유 대상은 <em>공유</em> 메뉴를 통해 사용자에게 노출됩니다.
-
- 이 기능을 사용하면 사용자가 다른 앱 내의 대상(예: 연락처)에 대해 콘텐츠를 공유할 수 있습니다.
- 예를 들어, 직접 공유 대상이 다른 소셜 네트워크 앱에서 액티비티를 시작하면 사용자가 해당 앱에 있는 특정 친구나 커뮤니티와 콘텐츠를 공유할 수 있습니다.
-
-</p>
-
-<p>직접 공유 대상을 활성화하려면 반드시 {@code android.service.}
- <br>
-{@code chooser.ChooserTargetService} 클래스를 확장하는 클래스를 정의해야 합니다. 매니페스트에서 {@code ChooserTargetService}를 선언하고
- 해당 선언 내에서 {@code BIND_CHOOSER_TARGET_SERVICE} 권한을 지정하고 {@code SERVICE_INTERFACE} 작업으로 인텐트 필터를 지정합니다.
-
-</p>
-<p>다음 예는 매니페스트에서 {@code ChooserTargetService}를 선언할 수 있는 방법입니다.
-</p>
-<pre>
-&lt;service android:name=".ChooserTargetService"
- android:label="&#64;string/service_name"
- android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE"&gt;
- &lt;intent-filter&gt;
- &lt;action android:name="android.service.chooser.ChooserTargetService" /&gt;
- &lt;/intent-filter&gt;
-&lt;/service&gt;
-</pre>
-
-<p>{@code ChooserTargetService}에 노출하고자 하는 액티비티마다 {@code &lt;meta-data&gt;} 요소를 하나씩 추가하고, 앱 매니페스트에 {@code "android.service.chooser.chooser_target_service"} 이름을 추가합니다.
-
-
-</p>
-
-<pre>
-&lt;activity android:name=".MyShareActivity”
- android:label="&#64;string/share_activity_label"&gt;
- &lt;intent-filter>
- &lt;action android:name="android.intent.action.SEND" /&gt;
- &lt;/intent-filter>
-&lt;meta-data
- android:name="android.service.chooser.chooser_target_service"
- android:value=".ChooserTargetService" /&gt;
-&lt;/activity>
-</pre>
-
-<h2 id="voice-interactions">음성 상호작용</h2>
-<p>
-이 미리 보기에서 제공하는 새로운 음성 상호작용 API는 <a href="https://developers.google.com/voice-actions/" class="external-link">음성 액션</a>과 같이 앱에 대화형 음성 환경을 구축할 수 있도록 합니다.
-
- {@code android.app.Activity.isVoiceInteraction()} 메서드를 호출하여 액티비티가 음성 액션에 대응하여 시작된 것인지 알아보세요.
-
- 이 경우에 해당되면, 앱이 {@code android.app.VoiceInteractor} 클래스를 사용하여 사용자로부터 음성 확인을 요청하거나, 선택 항목 목록에서 선택하게 하는 등 여러 가지 일을 할 수 있습니다.
-
- 음성 액션 구현에 대한 자세한 정보는 <a href="https://developers.google.com/voice-actions/interaction/" class="external-link">음성 액션 개발자 사이트</a>를 참조하세요.
-
-</p>
-
-<h2 id="assist">지원 API</h2>
-<p>
-이 미리 보기에서는 사용자가 도우미를 통해 앱에 참여하게 하는 새로운 방식을 제시합니다. 이 기능을 사용하려면, 사용자가 현재 컨텍스트를 사용하기 위해 도우미를 활성화해야 합니다.
- 일단 활성화하고 나면 <strong>홈</strong> 버튼을 길게 눌러 해당 도우미를 어느 앱에서나 불러낼 수 있습니다.
-</p>
-<p>앱이 현재 컨텍스트를 도우미와 공유하지 않기로 선택하는 경우, {@link android.view.WindowManager.LayoutParams#FLAG_SECURE} 플래그를 설정하면 됩니다.
- 플랫폼이 도우미에게 전달하는 일반적인 일련의 정보 외에도 앱이 추가적인 정보를 공유할 수 있도록 하려면 새로 나온 {@code android.app.Activity.AssistContent} 클래스를 사용할 수 있습니다.
-
-</p>
-
-<p>도우미에게 앱에서 가져온 추가 컨텍스트를 제공하려면, 다음 단계를 따르면 됩니다.</p>
-
-<ol>
-<li>{@link android.app.Application.OnProvideAssistDataListener} 인터페이스를 구현합니다.</li>
-<li>{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}를 사용하여 이 수신기를 등록합니다.
-</li>
-<li>액티비티에 따라 각기 다른 상황별 정보를 제공하려면 {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} 콜백을 재정의하고, 선택 사항으로 새로운 {@code Activity.onProvideAssistContent()} 콜백도 재정의합니다.
-
-
-</ol>
-
-<h2 id="notifications">알림</h2>
-<p>이 미리 보기에서는 알림 기능에 다음과 같은 API 변경을 추가합니다.</p>
-<ul>
- <li>새 {@code NotificationListenerService.INTERRUPTION_FILTER_ALARMS} 필터 수준이 추가되었습니다. 이것은 새로운 <em>알람 전용</em> 방해 금지 모드에 상응하는 것입니다.
-</li>
- <li>새 {@code Notification.CATEGORY_REMINDER} 카테고리 값이 추가되었습니다. 이것은 다른 이벤트로부터 사용자가 일정을 지정한 미리 알림({@link android.app.Notification#CATEGORY_EVENT}) 및 알람({@link android.app.Notification#CATEGORY_ALARM})를 구분하는 데 사용됩니다.
-
-
-</li>
- <li>새 {@code android.graphics.drawable.Icon} 클래스가 추가되었습니다. 이것은 {@code Notification.Builder.setSmallIcon(Icon)} 및 {@code Notification.Builder.setLargeIcon(Icon)} 메서드를 통해 알림에 첨부할 수 있습니다.
-
-</li>
- <li>새 {@code NotificationManager.getActiveNotifications()} 메서드가 추가되었습니다. 이것을 사용하면 앱이 자신의 알림 중 현재 활성 상태인 것이 무엇인지 알아낼 수 있습니다.
- 이 기능을 사용하는 앱 구현을 확인하려면 <a href="https://github.com/googlesamples/android-ActiveNotifications" class="external-link">활성 알림 샘플</a>을 참조하세요.
-</li>
-</ul>
-
-<h2 id="bluetooth-stylus">블루투스 스타일러스 지원</h2>
-<p>이 미리 보기에서는 블루투스 스타일러스를 사용하는 사용자 입력에 대한 지원을 개선하여 제공합니다. 사용자는 전화기나 태블릿을 호환되는 블루투스 스타일러스와 페어링하고 이에 연결할 수 있습니다.
- 연결된 동안 터치 스크린에서 가져온 위치 정보가 스타일러스에서 가져온 압력 및 버튼 정보와 합쳐져 하나의 터치 스크린을 사용할 때보다 훨씬 폭넓은 표현을 제공합니다.
-
- 앱이 스타일러스 버튼 누르기를 수신 대기하고 보조 작업을 수행하도록 하려면, 액티비티에 새로운 {@code View.onStylusButtonPressListener} 및 {@code GestureDetector.OnStylusButtonPressListener} 콜백을 등록하면 됩니다.
-
-
-</p>
-
-<p>스타일러스 버튼 상호작용을 감지하려면 {@link android.view.MotionEvent} 메서드와 상수를 사용하세요.
-</p>
-<ul>
-<li>사용자가 앱의 화면에 있는 버튼으로 스타일러스를 터치하면 {@link android.view.MotionEvent#getToolType(int) getTooltype()} 메서드가 {@link android.view.MotionEvent#TOOL_TYPE_STYLUS}를 반환합니다.
-
-</li>
-<li>M 미리 보기를 대상으로 삼는 앱의 경우, {@link android.view.MotionEvent#getButtonState() getButtonState()} 메서드는 사용자가 기본 스타일러스 버튼을 누르면 {@code MotionEvent.STYLUS_BUTTON_PRIMARY}를 반환합니다.
-
-
- 스타일러스에 두 번째 버튼이 있는 경우, 사용자가 그것을 누르면 같은 메서드가 {@code MotionEvent.STYLUS_BUTTON_SECONDARY}를 반환합니다.
- 사용자가 두 버튼을 동시에 누르는 경우, 이 메서드는 두 값을 'OR'로 함께 묶어 모두 반환합니다({@code STYLUS_BUTTON_PRIMARY|STYLUS_BUTTON_SECONDARY}).
-
-</li>
-<li>
-더 낮은 플랫폼 버전을 대상으로 하는 앱의 경우, {@link android.view.MotionEvent#getButtonState() getButtonState()} 메서드가 {@link android.view.MotionEvent#BUTTON_SECONDARY}(기본 스타일러스 버튼 누름)를 반환하고, {@link android.view.MotionEvent#BUTTON_TERTIARY}(보조 스타일러스 버튼 누름)를 반환하거나 둘 모두를 반환합니다.
-
-
-
-</li>
-</ul>
-
-<h2 id="ble-scanning">블루투스 저전력 스캔 개선</h2>
-<p>
-앱이 블루투스 저전력 스캔을 수행하는 경우, 새로운 {@code android.bluetooth.le.ScanSettings.Builder.setCallbackType()} 메서드를 사용해 콜백에 알림을 원하는 시점을 지정할 수 있습니다.즉, 정해진 {@link android.bluetooth.le.ScanFilter}에 일치하는 광고 패킷을 처음 찾았을 때와 이것을 일정한 시간 동안 확인하지 못했을 때에만 콜백에 알리도록 하면 됩니다.
-
-
-
- 스캔 기능에 대해 이런 식으로 접근하면 이전 버전의 플랫폼에서 제공되었던 것에 비해 훨씬 전력 효율적입니다.
-
-</p>
-
-<h2 id="hotspot">핫스팟 2.0 릴리스 1 지원</h2>
-<p>
-이 미리 보기에서는 Nexus 6 및 Nexus 9 기기에서의 핫스팟 2.0 릴리스 1 사양에 대한 지원을 추가합니다. 앱에 핫스팟 2.0 자격 증명을 프로비저닝하려면 {@link android.net.wifi.WifiEnterpriseConfig} 클래스의 새 메서드를 사용할 수 있습니다(예: {@code setPlmn()} 및 {@code setRealm()}).
-
-
- {@link android.net.wifi.WifiConfiguration} 객체에서는 {@link android.net.wifi.WifiConfiguration#FQDN} 및 {@code providerFriendlyName} 필드를 설정하면 됩니다. 새로 나온 {@code ScanResult.PasspointNetwork} 속성이 감지된 네트워크가 핫스팟 2.0 액세스 지점을 나타내는지 여부를 알려줍니다.
-
-
-
-</p>
-
-<h2 id="4K-display">4K 디스플레이 모드</h2>
-<p>이제 플랫폼에서 앱이 호환되는 하드웨어에서 디스플레이 해상도를 4K 렌더링으로 업그레이드하도록 요청할 수 있습니다.
- 현재의 물리적 해상도를 쿼리하려면 새로운 {@code android.view.Display.Mode} API를 사용할 수 있습니다.
- UI가 더 낮은 논리적 해상도에서 그려졌고 더 큰 물리적 해상도에 맞춰 확장된 경우, {@code Display.Mode.getPhysicalWidth()} 메서드가 반환하는 물리적 해상도가 {@link android.view.Display#getSize(android.graphics.Point) getSize()}가 보고하는 논리적 해상도와 다를 수 있다는 점을 유의하세요.
-
-
-</p>
-
-<p>앱이 실행되는 중에 시스템에 물리적 해상도를 변경하도록 요청할 수도 있습니다. 앱의 창에서 {@code WindowManager.LayoutParams.preferredDisplayModeId} 속성을 설정하면 됩니다.
- 이 기능은 4K 디스플레이 해상도로 전환하고자 하는 경우 무척 유용합니다.
- 4K 디스플레이 모드에서 UI는 계속 원래 해상도(예: 1080p)에서 렌더링되며 4K로 확장되지만, {@link android.view.SurfaceView} 객체는 원래 해상도에서 콘텐츠를 표시할 수 있습니다.
-
-</p>
-
-<h2 id="behavior-themeable-colorstatelists">테마 지정 가능 ColorStateLists</h2>
-<p>이제 M 미리 보기를 실행하는 기기에 대해 테마 속성이 {@link android.content.res.ColorStateList}에서 지원됩니다.
- {@link android.content.res.Resources#getColorStateList(int) getColorStateList()} 및 {@link android.content.res.Resources#getColor(int) getColor()} 메서드는 사용이 중단되었습니다.
-
- 이러한 API를 호출하려면, 대신 새로운 {@code Context.getColorStateList()} 또는 {@code Context.getColor()} 메서드를 호출하세요.
-
- 이 두 메서드는 v4 AppCompat 라이브러리에서도 {@link android.support.v4.content.ContextCompat}를 통해 이용할 수 있습니다.
-</p>
-
-<h2 id="audio">오디오 기능</h2>
-
-<p>이 미리 보기에서는 Android에서의 오디오 처리에 개선점을 더했습니다. </p>
-<ul>
- <li><a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a> 프로토콜을 지원하는 새로운 {@code android.media.midi} API를 추가했습니다.
- 이와 같은 API를 사용하면 MIDI 이벤트를 전송 및 수신할 수 있습니다.
-</li>
- <li>새 {@code android.media.AudioRecord.Builder} 및 {@code android.media.AudioTrack.Builder} 클래스를 추가하여 각각 디지털 오디오 캡처와 재생 객체를 생성하고, 오디오 소스와 싱크 속성을 구성하여 시스템 기본 설정을 재정의하도록 하였습니다.
-
-</li>
- <li>오디오 및 입력 기기를 연관시키기 위한 API Hook이 추가되었습니다. 이것은 특히 앱이 사용자에게 게임 컨트롤러 또는 Android TV에 연결된 리모컨에서 음성을 검색하는 데 유용합니다. 사용자가 검색을 시작하면 시스템이 새로운 {@code android.app.Activity.onSearchRequested()} 콜백을 호출합니다.
-
-
- 사용자의 입력 기기에 마이크가 내장되어 있는지 판별하려면, 해당 콜백에서 {@link android.view.InputDevice} 객체를 검색한 다음 새 {@code InputDevice.hasMic()} 메서드를 호출하면 됩니다.
-
-</li>
- <li>새 {@code android.media.AudioDevicesManager} 클래스를 추가하여 첨부된 소스와 싱크 오디오 기기 전체 목록을 검색할 수 있습니다.
- 이외에도, {@code android.media.OnAudioDeviceConnectionListener} 객체를 지정하여 오디오 기기가 연결되거나 연결 해제되었을 때 앱에 알릴 수도 있습니다.
-
-</li>
-</ul>
-
-<h2 id="video">비디오 기능</h2>
-<p>이 미리 보기에서는 비디오 처리 API에 새로운 기능을 추가합니다.</p>
-<ul>
-<li>새 {@code android.media.MediaSync} 클래스를 추가하여 여러 애플리케이션이 오디오와 비디오 스트림을 동기적으로 렌더링하는 데 지원하도록 하였습니다.
- 오디오 버퍼는 비블로킹 방식으로 제출된 다음 콜백을 통해 반환됩니다.
- 이것은 동적 재생 속도도 지원합니다.
-</li>
-<li>새 {@code MediaDrm.EVENT_SESSION_RECLAIMED} 이벤트를 추가하여 앱이 연 세션을 리소스 관리자가 회수했다는 내용을 나타낼 수 있습니다.
- 앱이 DRM 세션을 사용하는 경우, 이 이벤트를 처리해야 하고 회수된 세션을 사용하지 않도록 해야 합니다.
-
-</li>
-<li>새 {@code MediaCodec.CodecException.ERROR_RECLAIMED} 오류 코드를 추가했습니다. 이것은 코덱이 사용하는 미디어 리소스를 리소스 관리자가 회수했다는 내용을 나타냅니다.
- 이런 경우를 예외로 하고, 코덱은 종료 상태로 이동하면서 해제되어야 합니다.
-
-</li>
-<li>새 {@code MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances()} 인터페이스를 추가하여 지원되는 동시 코덱 인스턴스의 최대 수에 대한 힌트를 얻을 수 있습니다.
-
-</li>
-<li>새 {@code MediaPlayer.setPlaybackParams()} 메서드로는 빠른 재생 또는 느린 동작 재생에 대한 미디어 재생 속도를 설정할 수 있습니다.
- 이는 또한 비디오와 함께 오디오 재생을 자동으로 늘리거나 속도를 높이기도 합니다.
-</li>
-</ul>
-
-<h2 id="camera">카메라 기능</h2>
-<p>이 미리 보기에는 다음과 같은 새 API를 제공하여 카메라의 플래시에 액세스하고 이미지를 재처리하는 카메라에 액세스할 수 있도록 했습니다.
-</p>
-
-<h3 id="flashlight">Flashlight API</h3>
-<p>카메라 기기에 플래시 장치가 있는 경우, {@code CameraManager.setTorchMode()} 메서드를 호출하여 카메라 기기를 열지 않고도 플래시 장치의 Torch 모드를 켜거나 끌 수 있습니다.
- 앱에는 플래시 장치 또는 카메라 기기에 대한 독점적인 소유권이 없습니다.
- Torch 모드는 꺼져 있다가 카메라 기기를 이용할 수 없게 될 때마다 이용 불가능한 상태가 되고, Torch 모드를 켜진 상태로 유지하던 다른 카메라 리소스를 이용할 수 없게 되면 이용 불가능하게 됩니다.
-
- 다른 앱도 {@code setTorchMode()}를 호출하여 Torch 모드를 끌 수 있습니다.
- Torch 모드를 켠 마지막 앱이 종료되면 Troch 모드도 꺼집니다.
-</p>
-
-<p>Torch 모드 상태에 대해 알림을 받기 위한 콜백을 등록하려면 {@code CameraManager.registerTorchCallback()} 메서드를 호출하면 됩니다.
- 콜백을 처음 등록하면 그 즉시, 현재 알려진 모든 카메라 기기(플래시 장치가 있는)의 Torch 모드 상태와 함께 호출됩니다.
-
- Torch 모드가 성공적으로 켜지거나 꺼지면 {@code CameraManager.TorchCallback.onTorchModeChanged()} 메서드가 불려나옵니다.
-</p>
-
-<h3 id="reprocessing">재처리 API</h3>
-<p>{@link android.hardware.camera2 Camera2} API를 확장하여 YUV를 지원하고 비공개 불투명 형식 이미지 재처리를 지원하게 되었습니다.
- 앱은 재처리 기능을 이용할 수 있는지 알아보기 위해 {@code CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES}를 통합니다.
- 기기가 재처리를 지원하는 경우, 재처리 가능한 카메라 캡처 세션을 생성하려면 {@code CameraDevice.createReprocessableCaptureSession()}을 호출하고 입력 버퍼 재처리를 위한 요청을 생성하면 됩니다.
-
-
-</p>
-
-<p>{@code ImageWriter} 클래스를 사용하여 카메라 재처리 입력에 입력 버퍼 흐름을 연결시키세요.
- 빈 버퍼를 가져오려면 다음과 같은 프로그래밍 모델을 따르면 됩니다.</p>
-
-<ol>
-<li>{@code ImageWriter.dequeueInputImage()} 메서드를 호출합니다.</li>
-<li>입력 버퍼에 이 데이터를 채웁니다.</li>
-<li>{@code ImageWriter.queueInputImage()} 메서드를 호출하여 해당 버퍼를 카메라에 전송합니다.</li>
-</ol>
-
-<p>{@code ImageWriter} 객체와 {@code android.graphics.ImageFormat.PRIVATE} 이미지를 함께 사용하는 경우, 앱이 이미지 데이터에 직접 액세스할 수 없습니다.
-
- 대신, 버퍼 사본 없이 {@code ImageWriter.queueInputImage()} 메서드를 호출하여 {@code ImageFormat.PRIVATE} 이미지를 {@code ImageWriter}에 직접 전달하면 됩니다.
-
-</p>
-
-<p>이제 {@code ImageReader} 클래스가 {@code android.graphics.ImageFormat.PRIVATE} 형식 이미지 스트림을 지원합니다.
- 이로써 앱이 {@code ImageReader} 출력 이미지의 원형 이미지 대기열을 유지하고 하나 이상의 이미지를 선택하여 이들을 {@code ImageWriter}에 보내 카메라 재처리를 할 수 있습니다.
-
-</p>
-
-<h2 id="afw">Android for Work 기능</h2>
-<p>이 미리 보기에는 다음과 같은 Android for Work에 대한 새 API가 포함되어 있습니다.</p>
-<ul>
- <li><strong>회사 소유, 일회용 기기 제어 능력 향상:</strong> 이제 기기 소유자가 다음과 같은 설정을 제어하여 회사 소유, 일회용(COSU) 기기 관리를 한층 개선할 수 있습니다.
-
-
- <ul>
- <li>키가드를 비활성화하거나 다시 활성화하려면 {@code DevicePolicyManager.setKeyguardEnabledState()} 메서드를 사용하세요.
-</li>
- <li>상태 표시줄(빠른 설정, 알림과 Google Now를 시작하는 탐색 스와이프 업 동작 포함)을 비활성화하거나 다시 활성화하려면 {@code DevicePolicyManager.setStatusBarEnabledState()} 메서드를 사용하세요.
-
-</li>
- <li>안전 부팅을 비활성화하거나 다시 활성화하려면 {@link android.os.UserManager} 상수 {@code DISALLOW_SAFE_BOOT}를 사용하세요.
-</li>
- <li>플러그인 상태에서 화면이 꺼지지 않도록 방지하려면 {@link android.provider.Settings.Global} 상수 {@code STAY_ON_WHILE_PLUGGED_IN}을 사용하세요.
-</li>
- </ul>
- </li>
- <li><strong>기기 소유자의 앱 자동 설치 및 설치 제거:</strong> 이제 기기 소유자가 애플리케이션을 자동으로 설치하고 제거할 수 있습니다. 업무용 Google Play와는 따로 {@link android.content.pm.PackageInstaller} API를 사용하면 됩니다.
-
- 이제 사용자 상호작용 없이도 앱을 가져오고 설치하는 기기 소유자를 통해 기기를 프로비저닝할 수 있습니다.
- 이 기능은 Google 계정을 활성화하지 않고도 키오스크 또는 그와 같은 다른 기기를 원터치 방식으로 프로비저닝하는 데 유용합니다.
-</li>
-<li><strong>자동 엔터프라이즈 인증서 액세스: </strong> 사용자에게 인증서를 선택하라는 메시지가 표시되기 전에 앱이{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()}를 호출하는 경우, 이제 프로필 또는 기기 소유자가 {@code DeviceAdminReceiver.onChoosePrivateKeyAlias()}를 호출하여 요청하는 애플리케이션에 자동으로 별칭을 제공할 수 있습니다.
-
-
-
- 이 기능을 사용하면 관리된 앱에 사용자 상호작용 없이도 인증서에 대한 액세스 권한을 부여할 수 있습니다.
-</li>
-<li><strong>시스템 업데이트 자동 수락:</strong> 시스템 업데이트 정책을 {@code DevicePolicyManager.setSystemUpdatePolicy()}로 설정하면, 이제 기기 소유자가 자동으로 시스템 업데이트를 수락할 수 있습니다(예: 키오스크 기기의 경우). 또는 업데이트를 연기하거나 사용자가 업데이트를 수행하지 못하도록 최대 30일까지 막을 수 있습니다.
-
-
- 이에 더해, 관리자가 매일 시간 창을 설정하여 여기에서 업데이트를 수행하도록 할 수 있습니다. 예를 들어, 키오스크 기기를 사용하지 않는 시간 중에 업데이트하도록 합니다.
- 시스템 업데이트를 사용할 수 있게 되면 시스템이 작업 정책 컨트롤러 앱에 시스템 업데이트 정책이 설정되어 있는지 확인하고, 그에 따라 동작합니다.
-
-
-</li>
-<li>
-<strong>인증서 설치 위임:</strong> 이제 프로필 또는 기기 소유자가 타사 앱에 권한을 부여하여 다음과 같은 {@link android.app.admin.DevicePolicyManager} 인증서 관리 API를 호출할 수 있습니다.
-
-
-<ul>
- <li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
-getInstalledCaCerts()}</li>
- <li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
-hasCaCertInstalled()}</li>
- <li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
-installCaCert()}</li>
- <li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
-uninstallCaCert()}</li>
- <li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
-uninstallAllUserCaCerts()}</li>
- <li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
-installKeyPair()}</li>
-</ul>
-</li>
-<li><strong>엔터프라이즈 공장 재설정 보호:</strong> 기기 소유자를 프로비저닝하는 경우, 이제 {@code DeviceManagerPolicy.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS} 번들을 설정하여 공장 재설정 보호(FRP)를 잠금 해제하는 데 사용되는 매개변수를 구성할 수 있습니다.
-
- 이와 같은 매개변수는 기기를 재설정하여 FRP를 잠금 해제하도록 하고 기기를 프로비저닝하기로 한 다음에 NFC 프로그래머 앱이 제공할 수 있으며, 이전에 구성한 Google 계정도 필요하지 않습니다.
-
- 이와 같은 매개변수를 수정하지 않으면 FRP가 제자리에 유지되어 이전에 활성화한 Google 자격 증명 없이는 기기가 활성화되지 않도록 방지합니다.
-
-
-<p>이외에도 Google Play 서비스에 앱 제한을 설정하면 기기 소유자가 기기에서 활성화된 것을 대신할 대체 Google 계정을 지정하여 FRP를 잠금 해제하는 데 사용할 수 있습니다.
-</p>
-</li>
-<img src="{@docRoot}preview/images/work-profile-screen.png" srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x" style="float:right; margin:0 0 10px 20px" width="282" height="476" />
-<li><strong>데이터 사용량 추적:</strong> 새로운 {@code android.app.usage.NetworkStatsManager} 메서드를 사용하여 이제 프로필 또는 기기 소유자가 <strong>설정 &gt; 데이터</strong>에 표시되는 데이터 사용량 통계를 쿼리할 수 있습니다.
-
- 프로필 소유자에게는 자신이 관리하는 프로필에서 데이터를 쿼리할 권한이 자동으로 부여되는 반면, 기기 소유자의 경우에는 관리된 기본 사용자의 사용량 데이터에 대한 액세스 권한이 주어집니다.
-
-</li>
-<li><strong>런타임 권한 관리:</strong>
-<p>프로필 또는 기기 소유자는 모든 애플리케이션의 모든 런타임 요청에 대해 권한 정책을 설정할 수 있습니다. {@code DevicePolicyManager.setPermissionPolicy()}를 사용해 사용자에게 정상적으로 권한을 부여하라는 메시지를 표시하거나, 자동으로 권한을 허용하거나 해당 권한을 자동으로 거부하도록 할 수도 있습니다.
-
-
- 후자의 정책이 설정된 경우, 사용자는 앱의 <strong>설정</strong> 내에 있는 권한 화면 안에서 프로필 또는 기기 소유자가 선택한 내용을 수정할 수 없습니다.
-
-</p></li>
-<li><strong>설정 VPN:</strong> 이제 VPN 앱이 <strong>설정 &gt; 더 보기 &gt; VPN</strong>에 표시됩니다. 이외에도, VPN 사용량에 수반되는 알림은 이제 VPN 구성 방식만 구체적으로 다루게 되었습니다.
-
-
- 프로필 소유자의 경우, 이러한 알림은 VPN이 관리된 프로필에 대해 구성되었는지, 아니면 개인 프로필에 구성되었거나 둘 모두에 구성되었는지 여부에 한정됩니다.
- 기기 소유자의 경우, 이 알림은 VPN이 기기 전체에 대해 구성되었는지 여부만 나타냅니다.
-</li>
-<li><strong>작업 상태 알림:</strong> 이제 관리된 프로필에서 온 앱에 전경에 있는 액티비티가 있을 때마다 상태 표시줄 서류가방 아이콘이 나타납니다.
- 또한, 기기가 관리된 프로필 내 앱의 액티비티에 대해 직접 잠금 해제된 경우, 알림 메시지가 표시되어 사용자에게 지금 작업 프로필 내에 있다는 사실을 알려주기도 합니다.
-
-
-</li>
-</ul>
-
-<p class="note">
- M 개발자 미리 보기의 모든 API 변경 내용에 대한 상세한 정보는 <a href="{@docRoot}preview/download.html">API 차이점 보고서</a>를 참조하세요.
-</p>
diff --git a/docs/html-intl/intl/ko/preview/backup/index.jd b/docs/html-intl/intl/ko/preview/backup/index.jd
deleted file mode 100644
index b3952d5eab52..000000000000
--- a/docs/html-intl/intl/ko/preview/backup/index.jd
+++ /dev/null
@@ -1,327 +0,0 @@
-page.title=앱용 자동 백업
-page.tags=backup, previewresources, androidm
-page.keywords=백업, 자동 백업, 미리 보기
-page.image=images/cards/card-auto-backup_2x.png
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#overview">개요</a></li>
- <li><a href="#configuring">데이터 백업 구성</a></li>
- <li><a href="#testing">백업 구성 테스트</a></li>
- <li><a href="#issues">알려진 문제</a></li>
- </ol>
- </div>
-</div>
-
-<p>
- 사용자는 앱 내에서 데이터를 생성하고 기본 설정을 설정하는 데 상당한 시간과 노력을 들이는 경우가 빈번합니다.
- 사용자가 고장 난 기기를 교체하거나 새것으로 업그레이드하면 그러한 데이터를 보존해 두는 것이 훌륭한 사용자 환경을 보장하는 데 중요한 부분을 차지합니다.
- Android M 미리 보기 시스템에서 실행되는 기기는 이러한 상황에서 사용자에게 좋은 환경을 보장하는 데 도움을 주기 위해 앱 데이터를 Google Drive에 자동으로 백업합니다.
-
- 이런 앱 데이터는 사용자가 기기를 바꾸거나 업그레이드하면 자동으로 복원됩니다.
-
-</p>
-
-<p>
- 자동 백업 기능은 Android M 미리 보기에서 실행되는 기기에 설치된 모든 앱에 활성화되어 있습니다. 달리 앱 코드를 추가하지 않아도 됩니다.
- 시스템은 사용자에게 자동 데이터 백업에서 옵트아웃할 수도 있습니다.
- 앱에서 어떤 데이터를 백업할지 제한하는 쪽을 선택할 수도 있습니다.
-</p>
-
-<p>
- 이 문서에서는 새로운 시스템 동작과 앱에 대해 어느 데이터를 백업할지 지정하는 방법을 설명합니다.
-
-</p>
-
-<h2 id="overview">개요</h2>
-
-<p>
- 자동 백업 기능은 앱이 사용자 기기에서 생성한 데이터를 보존하기 위해 해당 데이터를 사용자의 Google Drive 계정에 업로드하고 암호화합니다.
- 데이터 저장에 대해 개발자나 사용자에게 아무런 요금도 부과하지 않고, 저장된 데이터는 사용자 개인의 Drive 할당량을 사용한 것으로 감안하지 않습니다.
- M 미리 보기 시행 기간 중 사용자는 Android 앱 한 개당 최대 25MB까지 저장할 수 있습니다.
-
-</p>
-
-<p>
- 자동 백업은 24시간마다 한 번씩, 기기가 유휴 상태일 때, 충전 중일 때 및 Wi-Fi 네트워크에 연결될 때마다 수행합니다.
- 이러한 조건에 부합하면 백업 관리자 서비스가 이용 가능한 모든 백업 데이터를 클라우드에 업로드합니다.
- 사용자가 새 기기로 전환하거나 백업된 앱을 제거했다가 다시 설치하면 복원 작업이 백업된 데이터를 새로 설치된 앱의 데이터 디렉터리 안에 복사합니다.
-
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> 레거시 <a href="{@docRoot}google/backup/index.html">Android 백업 서비스</a>를 이용하는 앱의 경우, 이 새 동작이 적용되지 않고 기존 백업 동작이 평소처럼 작동합니다.
-
-
-</p>
-
-
-<h3 id="auto-exclude">자동으로 배제된 데이터 파일</h3>
-
-<p>
- 데이터 중에는 예를 들어 임시 파일과 캐시 등 백업하지 않아도 되는 것도 있습니다. 따라서 자동 백업 서비스는 특정 데이터 파일을 기본적으로 배제합니다.
-
-</p>
-
-<ul>
- <li>디렉터리 내의 파일 중 {@link android.content.Context#getCacheDir
- getCacheDir()} 및 {@link android.content.ContextWrapper#getCodeCacheDir getCodeCacheDir()}
- 메서드로 참조되는 파일.
- </li>
-
- <li>외부 저장소에 위치한 파일 중(디렉터리에 상주하는 것이 아닌 한)
-{@link android.content.Context#getExternalFilesDir getExternalFilesDir()}
- 메서드로 참조되는 파일.
- </li>
-
- <li>디렉터리에 위치한 파일 중
-{@link android.content.Context#getNoBackupFilesDir getNoBackupFilesDir()} 메서드로 참조되는 파일.
- </li>
-</ul>
-
-<h2 id="configuring">데이터 백업 구성</h2>
-
-<p>
- M 미리 보기 기기에 설치된 앱이 생성한 데이터는 모두 백업됩니다. 다만 이전 섹션에서 나열한 자동으로 배제되는 파일만은 예외입니다.
- 앱에서 어느 데이터를 백업할지 좀 더 상세하게 제한하고 구성하려면 앱 매니페스트에 있는 설정을 사용하면 됩니다.
-
-</p>
-
-<h3 id="include-exclude">데이터 포함 또는 배제</h3>
-
-<p>
- 앱에 필요한 데이터가 무엇이며 어떤 식으로 저장하는지에 따라 특정 파일이나 디렉터리를 포함 또는 배제하기 위해 특정한 규칙을 설정해야 할 수 있습니다.
- 자동 백업 서비스는 이러한 백업 규칙 설정을 지원하는 데 XML 구성 파일과 앱 매니페스트를 사용하는 방식을 씁니다.
-
- 앱 매니페스트에서는 다음 예에서 표시된 것처럼 백업 구성표 구성 파일을 지정하면 됩니다.
-
-</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.my.appexample"&gt;
- &lt;uses-sdk android:minSdkVersion="MNC"/&gt;
- &lt;uses-sdk android:targetSdkVersion="MNC"/&gt;
- &lt;app ...
-<strong> android:fullBackupContent="&#64;xml/mybackupscheme"&gt;</strong>
- &lt;/app&gt;
- ...
-&lt;/manifest&gt;
-</pre>
-
-<p>
- 이 예시 코드에서는 <code>android:fullBackupContent</code> 특성이 XML 파일을 나타냅니다. 이는 앱 개발 프로젝트의 <code>res/xml/</code> 디렉터리 내에 위치하며, 일명 <code>mybackupscheme.xml</code>이라고 합니다.
-
- 이 구성 파일에는 어느 파일이 백업되는지에 대한 규칙이 포함되어 있습니다.
- 다음 예시 코드는 특정 파일을 백업에서 배제하는 구성 파일을 나타낸 것입니다.
-
-</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;full-backup-content&gt;
- &lt;exclude domain="database" path="device_info.db"/&gt;
-&lt;/full-backup-content&gt;
-</pre>
-
-<p>
- 이 예에서의 백업 구성은 특정 데이터베이스 파일만 백업되지 않게 배제합니다.
- 나머지 파일은 모두 백업됩니다.
-</p>
-
-<h4>백업 구성 구문</h4>
-
-<p>
- 백업 서비스 구성을 사용하면 구체적으로 어느 파일을 백업에 포함시키고 백업에서 배제할지 지정할 수 있게 해줍니다.
- 데이터 백업 구성 XML 파일에 사용되는 구문은 다음과 같습니다.
-</p>
-
-<pre>
-&lt;full-backup-content&gt;
- &lt;include domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string" /&gt;
- &lt;exclude domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string" /&gt;
-&lt;/full-backup-content&gt;
-</pre>
-
-<p>
- 다음의 요소와 특성을 사용하면 어느 파일을 백업에 포함시키거나 백업에서 배제할지 지정할 수 있게 해줍니다.
-
-</p>
-
-<ul>
- <li>
- <code>&lt;include&gt;</code>. 이 요소는 일련의 리소스를 백업하기로 지정하는 경우 사용하십시오. 시스템이 기본적으로 앱 안의 모든 데이터를 백업하는 대신 이 방식을 쓰면 됩니다.
- 예를 들어 <code>&lt;include&gt;</code> 태그를 지정하면 시스템은 이 요소로 <em>지정된 리소스만</em> 백업합니다.
-
-
- </li>
-
- <li>
- <code>&lt;exclude&gt;</code>. 이 요소는 일련의 리소스를 백업에서 배제하기로 지정하는 데 사용하세요.
- 시스템이 앱 안의 모든 데이터를 백업하되, 이 요소로 지정된 리소스만 제외합니다.
-
- </li>
-
- <li>
- <code>domain.</code> 백업에 포함시키거나 백업에서 배제하고자 하는 리소스 유형입니다. 이 특성에 대해 지정할 수 있는 유효한 값에는 다음과 같은 것들이 있습니다.
-
- </li>
-
- <li style="list-style: none">
- <ul>
- <li>
- <code>root</code>. 리소스가 앱의 루트 디렉터리에 있음을 나타냅니다.
- </li>
-
- <li>
- <code>file</code>. 디렉터리 내에 있는 리소스 중
- {@link android.content.Context#getFilesDir getFilesDir()} 메서드에 의해 반환된 것에 상응합니다.
- </li>
-
- <li>
- <code>database</code>.
- {@link android.content.Context#getDatabasePath getDatabasePath()} 메서드에 의해, 또는
- {@link android.database.sqlite.SQLiteOpenHelper} 클래스를 사용하여 반환된 데이터베이스에 상응합니다.
- </li>
-
- <li>
- <code>sharedpref</code>. {@link android.content.Context#getSharedPreferences getSharedPreferences()}
- 메서드에 의해 반환된 {@link android.content.SharedPreferences} 객체에
- 상응합니다.
- </li>
-
- <li>
- <code>external</code>. 리소스가 외부 저장소에 있으며, 디렉터리 내의 파일 중 {@link android.content.Context#getExternalFilesDir getExternalFilesDir()} 메서드에 의해 반환된 것에 상응합니다.
-
-
- </li>
-
- <li>
- <code>path</code>. 백업에 포함시키거나 백업에서 배제하고자 하는 리소스로 이어지는 파일 경로입니다.
-
- </li>
- </ul>
- </li>
-</ul>
-
-
-<h3 id="prohibit">데이터 백업 금지하기</h3>
-
-<p>
- 앱 데이터 중 어떤 것이라도 자동 백업을 방지하기로 선택할 수도 있습니다. 매니페스트의 앱 요소에서 <code>android:allowBackup</code> 특성을 <code>false</code>로 설정하면 됩니다.
-
- 이 설정은 다음 예시 코드로 설명해 놓았습니다.
-</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.my.appexample"&gt;
- &lt;uses-sdk android:minSdkVersion="MNC"/&gt;
- &lt;uses-sdk android:targetSdkVersion="MNC"/&gt;
- &lt;app ...
-<strong> android:allowBackup="false"&gt;</strong>
- &lt;/app&gt;
- ...
-&lt;/manifest&gt;
-</pre>
-
-
-<h2 id="testing">백업 구성 테스트</h2>
-
-<p>
- 백업 구성을 만들었으면 앱이 데이터를 저장하고 제대로 복구되는지 확인하기 위해 테스트해보는 것이 좋습니다.
-
-</p>
-
-
-<h4>백업 로깅 활성화</h4>
-
-<p>
- 백업 기능이 XML 파일을 구문 분석하는 방법을 결정하는 데 도움이 되는 방법으로 테스트 백업을 수행하기 전에 로깅을 활성화하는 방안이 있습니다.
-
-</p>
-
-<pre class="noprettyprint">
-$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE
-</pre>
-
-<h4>백업 테스트</h4>
-
-<p>수동으로 백업을 실행하려면, 우선 다음과 같은 명령을 호출하여 백업 관리자를 초기화해야 합니다.
-
-</p>
-
-<pre class="noprettyprint">
-$ adb shell bmgr run
-</pre>
-
-<p>
- 다음으로, 다음과 같은 명령을 사용하여 애플리케이션을 수동으로 백업하되 앱의 패키지 이름을 <code>&lt;PACKAGE&gt;</code> 매개변수로 지정합니다.
-
-</p>
-
-<pre class="noprettyprint">
-$ adb shell bmgr fullbackup &lt;PACKAGE&gt;</pre>
-
-
-<h4>복구 테스트</h4>
-
-<p>
- 앱 데이터를 백업한 다음 수동으로 복구를 시작하려면, 다음 명령을 호출하되, 앱에 대한 패키지 이름을 <code>&lt;PACKAGE&gt;</code> 매개변수로 지정하십시오.
-
-</p>
-
-<pre class="noprettyprint">
-$ adb shell bmgr restore &lt;PACKAGE&gt;
-</pre>
-
-<p class="warning">
- <b>경고:</b> 이 작업을 수행하면 앱이 중지되고 복구 작업을 수행하기 전에 데이터를 지워버립니다.
-
-</p>
-
-<p>
- 앱의 복구 프로세스를 시작하려면 앱을 제거했다가 다시 설치하면 됩니다. 앱 데이터는 앱 설치가 완료되면 클라우드에서 자동으로 복원됩니다.
-
-</p>
-
-
-<h4>백업 문제 해결</h4>
-
-<p>
- 문제에 직면하면 백업 데이터와 관련 메타데이터를 지우면 됩니다. 그러려면 <strong>설정 &gt; 백업</strong>에서 백업을 껐다가 켜거나, 기기를 공장 재설정하거나 아니면 다음의 명령을 호출하십시오.
-
-
-</p>
-
-<pre>$ adb shell bmgr wipe &lt;TRANSPORT&gt; &lt;PACKAGE&gt;</pre>
-
-<p>
- <code>&lt;TRANSPORT&gt;</code> 값이 <code>com.google.android.gms</code>로 접두사가 붙어있어야 합니다.
- 전송 목록을 가져오려면 다음과 같은 명령을 호출하면 됩니다.
-</p>
-
-<pre>$ adb shell bmgr list transports</pre>
-
-<h2 id="issues">알려진 문제</h2>
-
-<p>다음은 자동 백업 서비스에 대해 알려진 문제입니다.</p>
-
-<ul>
- <li><strong>Google Cloud 메시지</strong> - 푸시 알림에 Google Cloud 메시지를 사용하는 앱의 경우, Google Cloud 메시지 등록에 의해 반환된 등록 ID를 백업하면 복원된 앱에 대한 푸시 알림을 끊게 되는 문제가 알려져 있습니다. 새 기기에 설치된 다음에는 새 등록 ID에 대하여 API를 쿼리하는 것이 중요합니다. 이것은 기존 등록 ID가 백업된 경우는 해당되지 않습니다.
-
-
-
-
- 이 문제를 피하려면 백업된 파일 집합에서 등록 ID를 배제하십시오.
-
- </li>
-</ul>
diff --git a/docs/html-intl/intl/ko/preview/behavior-changes.jd b/docs/html-intl/intl/ko/preview/behavior-changes.jd
deleted file mode 100644
index fa9507056b72..000000000000
--- a/docs/html-intl/intl/ko/preview/behavior-changes.jd
+++ /dev/null
@@ -1,402 +0,0 @@
-page.title=동작 변경
-page.keywords=미리 보기, SDK, 호환성
-sdk.platform.apiLevel=MNC
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>이 문서의 내용</h2>
-
-<ol id="toc44" class="hide-nested">
- <li><a href="#behavior-runtime-permissions">런타임 권한</a></li>
- <li><a href="#behavior-power">절전 최적화</a>
- <ol>
- <li><a href="#behavior-doze">Doze</a></li>
- <li><a href="#behavior-app-standby">앱 대기 모드</a></li>
- </ol>
- </li>
- <li><a href="#behavior-adoptable-storage">채택 가능한 저장소 기기</a></li>
- <li><a href="#behavior-apache-http-client">Apache HTTP 클라이언트 제거</a></li>
- <li><a href="#behavior-audiomanager-Changes">AudioManager 변경</a></li>
- <li><a href="#behavior-test-selection">텍스트 선택</a></li>
- <li><a href="#behavior-keystore">Android 키노트 변경</a></li>
- <li><a href="#behavior-network">Wi-Fi 및 네트워킹 변경</a></li>
- <li><a href="#behavior-camera">카메라 서비스 변경</a></li>
- <li><a href="#behavior-art-runtime">ART 런타임</a></li>
- <li><a href="#behavior-apk-validation">APK 유효성 검사</a></li>
- <li><a href="#behavior-afw">Android for Work 변경</a></li>
-</ol>
-
-<h2>API 차이점</h2>
-<ol>
-<li><a href="{@docRoot}preview/download.html">M 미리 보기에 대한 API 레벨 22 &raquo;</a> </li>
-</ol>
-
-
-<h2>참고 항목</h2>
-<ol>
-<li><a href="{@docRoot}preview/api-overview.html">M 개발자 미리 보기 API 개요</a> </li>
-</ol>
-
-</div>
-</div>
-
-<p>M 개발자 미리 보기에는 새로운 기능 및 특징과 더불어 다양한 시스템 변경과 API 동작 변경 내용이 포함되어 있습니다.
- 이 문서에서는 개발자 여러분이 숙지해야 하고 앱을 개발할 때 감안해야 하는 몇 가지 주요 변경 내용을 소개하겠습니다.
-</p>
-
-<p>이전에 Android용 앱을 게시한 적이 있는 경우, 이와 같은 플랫폼 변경으로 인해 앱이 영향을 받을 수 있다는 점을 유의하세요.
-</p>
-
-<h2 id="behavior-runtime-permissions">런타임 권한</h1>
-<p>이 미리 보기에서는 새 권한 모델을 소개합니다. 여기에서는 이제 사용자가 런타임에 직접 앱 권한을 관리할 수 있게 됩니다.
- 이 모델을 사용하면 사용자에게 개선된 가시성과 권한에 대한 제어권을 부여하는 한편 앱 개발자에게는 설치와 자동 업데이트 과정을 간소화해줍니다. 사용자는 설치된 여러 앱에 대해 따로따로 권한을 허용하거나 취소할 수 있습니다.
-
- </p>
-
-<p>M 미리 보기를 대상으로 하는 앱을 개발하는 경우, 권한 확인과 요청은 런타임에 해야 합니다.
- 앱에 어떤 권한이 허용되었는지 판단하려면, 새로운 {@code Context.checkSelfPermission()} 메서드를 호출하면 됩니다.
- 권한을 요청하려면 새 {@code Activity.requestPermission()} 메서드를 호출하세요.
- 앱이 M을 대상으로 하지 않더라도, 앱을 새 권한 모델에서 테스트해보는 것이 좋습니다.
-</p>
-
-<p>앱에서 새 권한 모델을 지원하는 방법에 대한 자세한 내용은 <a href="{@docRoot}preview/features/runtime-permissions.html">권한</a> 개발자 미리 보기 페이지를 참조하세요.
-
- 앱에 미친 영향을 평가하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">테스트 가이드</a>를 참조하세요.
-</p>
-
-<h2 id="behavior-power">절전 최적화</h2>
-<p>이 미리 보기에서는 유휴 상태의 기기 및 앱에 대한 새로운 절전 최적화 기능을 소개합니다.</p>
-
-<h3 id="behavior-doze">Doze</h3>
-<p>기기의 플러그가 뽑히고 화면이 꺼진 채로 일정 시간 동안 변화 없는 상태로 유지되면, <em>Doze</em> 상태로 들어갑니다. 이 상태에서는 기기가 시스템을 절전 모드 상태로 유지하려 시도합니다.
- 이 모드에서 기기는 정기적으로 잠시 동안 정상 작동을 재개하여 앱 동기화가 일어날 수 있도록 하고 보류된 작업이 있으면 시스템이 이를 수행할 수 있도록 합니다.
-
-</p>
-
-<p>앱이 Doze 상태에 있는 동안 다음과 같은 제한 사항이 적용됩니다.</p>
-<ul>
-<li>네트워크 액세스가 비활성화됩니다. 다만 앱이 우선 순위가 높은 Google Cloud 메시지 Tickle을 받을 때는 예외입니다.
-</li>
-<li><a href="{@docRoot}reference/android/os/PowerManager.WakeLock.html">절전 모드 해제 잠금</a>이 무시됩니다.</li>
-<li>{@link android.app.AlarmManager} 클래스로 일정이 예약된 알람이 비활성화됩니다. 다만 {@link android.app.AlarmManager#setAlarmClock setAlarmClock()} 메서드 및 {@code AlarmManager.setAndAllowWhileIdle()}로 설정한 알람은 예외입니다.
-
-</li>
-<li>WiFi 스캔을 수행하지 않습니다.</li>
-<li>동기화 어댑터와 {@link android.app.job.JobScheduler}의 동기화와 작업 실행이 금지됩니다.
-</li>
-</ul>
-</p>
-<p>기기가 Doze 모드를 종료하면 보류되어 있던 작업과 동기화를 모두 실행합니다.</p>
-<p>이 기능을 테스트하려면 개발 머신에 M 미리 보기를 실행하는 기기를 연결하여 다음과 같은 명령을 호출하면 됩니다.
-
-</p>
-<pre class="no-prettyprint">
-$ adb shell dumpsys battery unplug
-$ adb shell dumpsys deviceidle step
-$ adb shell dumpsys deviceidle -h
-</pre>
-<p class="note"><strong>참고:</strong> 다가오는 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud 메시지</a> 릴리스에서는 개발자에게 우선 순위가 높은 메시지를 지정하게 해줍니다.
-
-
- 앱이 우선 순위가 높은 GCM 메시지를 수신하면 이 앱에는 기기가 Doze 모드에 있더라도 잠시 네트워크 액세스가 허용됩니다.
-
-</p>
-
-<p>앱에서 Doze를 테스트하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#doze-standby">테스트 가이드</a>를 참조하세요.
-
- </p>
-
-<h3 id="behavior-app-standby">앱 대기 모드</h3>
-<p>이 미리 보기에서는 시스템이 보기에 앱이 활성 사용 중이 아닌 경우 해당 앱은 유휴 상태라고 판별할 수 있습니다.
- 일정 시간이 지나면 앱이 유휴 상태인 것으로 간주되는데, 시스템이 다음과 같은 신호 중 하나를 감지하는 경우는 예외입니다.
-</p>
-
-<ul>
-<li>사용자가 명시적으로 앱을 시작했습니다.</li>
-<li>앱에 현재 전경에 있는 프로세스가 있습니다(액티비티 또는 전경 서비스 중 하나의 형태로, 또는 다른 액티비티나 전경 서비스가 사용 중인 상태로).
-</li>
-<li>앱이 알림을 생성하여 사용자가 그것을 잠금 화면에서 보거나 알림 트레이에서 확인합니다.
-</li>
-<li><strong>설정</strong>을 통해 사용자가 명시적으로 앱이 최적화에서 면제되도록 요청합니다.
-</li>
-</ul>
-
-<p>기기의 플러그가 뽑혀 있는 경우, 유휴 상태인 것으로 간주된 앱은 자신의 네트워크 액세스를 비활성화하고 동기화와 작업을 일시 중단시킵니다.
- 기기가 전원 공급 장치에 연결되면 이와 같은 앱에 네트워크 액세스가 허용되며 보류 중이었던 작업과 동기화를 모두 실행할 수 있습니다.
- 기기가 오랜 시간 동안 유휴 상태인 경우, 유휴 앱에는 하루에 한 번 정도 네트워크 액세스가 허용됩니다.
-</p>
-
-<p>이 기능을 테스트하려면 개발 머신에 M 미리 보기를 실행하는 기기를 연결하여 다음과 같은 명령을 호출하면 됩니다.
-
-</p>
-<pre class="no-prettyprint">
-$ adb shell dumpsys battery unplug
-$ adb shell am set-idle &lt;packageName&gt; true
-$ adb shell am set-idle &lt;packageName&gt; false
-$ adb shell am get-idle &lt;packageName&gt;
-</pre>
-
-<p class="note"><strong>참고:</strong> 다가오는 <a href="https://developers.google.com/cloud-messaging/" class="external-link">Google Cloud 메시지</a>(GCM) 릴리스에서는 개발자에게 우선 순위가 높은 메시지를 지정할 수 있습니다.
-
-
- 앱이 우선 순위가 높은 GCM 메시지를 수신하면 이 앱에는 앱이 유휴 상태에 있더라도 잠시 네트워크 액세스가 허용됩니다.
-
-</p>
-
-<p>앱에서 앱 대기 모드를 테스트하는 방법에 대한 팁은 <a href="{@docRoot}preview/testing/guide.html#doze-standby">테스트 가이드</a>를 참조하세요.
-
- </p>
-
-<h2 id="behavior-adoptable-storage">채택 가능한 저장소 기기</h2>
-<p>
-이 미리 보기에서는 사용자가 SD 카드와 같은 외부 저장소 기기를 <em>채택</em>할 수 있습니다. 외부 저장소 기기를 채택하면 기기를 암호화하고 포맷하여 내부 저장소처럼 작동하도록 합니다.
- 이 기능을 사용하면 사용자가 앱과 해당 앱의 비공개 데이터를 여러 저장소 기기 사이에서 이동시킬 수 있습니다.
- 앱을 이동시키는 경우, 시스템은 매니페스트의 <a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a> 기본 설정을 사용합니다.
-
-
-</p>
-
-<p>앱이 다음과 같은 API 또는 필드에 액세스하는 경우, 앱이 내부 및 외부 저장소 기기 사이를 이동하면서 반환하는 파일 경로가 급격하게 달라진다는 점을 유의하세요. 파일 경로를 구축할 때에는 이와 같은 API를 항상 동적으로 호출하는 것을 강력히 권장합니다. 하드코드된 파일 경로를 사용하거나 이전에 구축된 정규화된 파일 경로를 유지하지 마세요.
-
-
-</p>
-
-<ul>
-<li>{@link android.content.Context} 메서드:
- <ul>
- <li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
- <li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
- <li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
- <li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
- <li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
- <li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
- <li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
- <li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
- <li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
- </ul>
-</li>
-<li>{@link android.content.pm.ApplicationInfo} 필드:
- <ul>
- <li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
- <li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
- <li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
- <li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
- <li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
- <li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
- </ul>
-</li>
-</ul>
-
-<p>개발자 미리 보기에서 이 기능을 디버그하려면, 다음 명령을 실행하여 USB On-The-Go(OTG) 케이블을 통해 Android 기기에 연결된 USB 드라이브 채택을 활성화하면 됩니다.
-</p>
-
-<pre class="no-prettyprint">
-$ adb shell sm set-force-adoptable true
-</pre>
-
-<h2 id="behavior-apache-http-client">Apache HTTP 클라이언트 제거</h2>
-<p>이 미리 보기에서는 Apache HTTP 클라이언트에 대한 지원을 제거합니다. 앱이 이 클라이언트를 사용하고 Android 2.3(API 레벨 9) 이상을 대상으로 하는 경우, {@link java.net.HttpURLConnection} 클래스를 대신 사용하세요.
-
- 이는 투명한 압축과 응답 캐싱을 통해 네트워크 사용량을 줄이고 전력 소모를 최소화하기 때문에 API가 더 효율적입니다.
- Apache HTTP API를 계속 사용하려면 우선 다음과 같은 컴파일-시간 종속성을 {@code build.gradle} 파일에서 선언해야 합니다.
-
-</p>
-<pre>
-android {
- useLibrary 'org.apache.http.legacy'
-}
-</pre>
-<p>Android는 OpenSSL에서 <a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a> 라이브러리로 옮겨갑니다.
-
- 앱에서 Android NDK를 사용하는 경우, NDK API의 일부분이 아닌 암호화 라이브러리에 대해 링크를 연결하지 마세요(예:{@code libcrypto.so} 및 {@code libssl.so}).
- 이러한 라이브러리는 공개 API가 아니며, 여러 릴리스와 기기에 걸쳐 통보 없이 변경되거나 중단될 수 있으며 스스로를 보안 취약점에 노출시킬 수도 있습니다.
-
- 대신에 원래 코드를 수정하여 JNI를 통해 Java 암호화 API를 호출하도록 하거나, 직접 선택한 암호화 라이브러리에 대해 정적으로 연결하도록 하세요.
-
-</p>
-
-<h2 id="behavior-audiomanager-Changes">AudioManager 변경</h2>
-<p>볼륨을 직접 설정하거나 특정 스트림을 {@link android.media.AudioManager} 클래스를 통해 음소거하는 것은 이제 더 이상 지원되지 않습니다.
- {@link android.media.AudioManager#setStreamSolo(int,boolean)
-setStreamSolo()} 메서드는 사용이 중단되었으며, 그 대신 {@code AudioManager.requestAudioFocus()} 메서드를 호출해야 합니다.
- 이와 마찬가지로, {@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} 메서드도 사용이 중단되었습니다. 그 대신 {@code AudioManager.adjustStreamVolume()} 메서드를 호출하고 방향 값 {@code ADJUST_MUTE} 또는 {@code ADJUST_UNMUTE}에서 전달해야 합니다.
-
-
-</p>
-
-<h2 id="behavior-test-selection">텍스트 선택</h2>
-
-<img src="{@docRoot}preview/images/text-selection.gif" style="float:right; margin:0 0 20px 30px" width="360" height="640" />
-
-<p>사용자가 앱에서 텍스트를 선택하면 이제 텍스트 선택 작업을 표시할 수 있습니다. 예를 들어 <em>잘라내기</em>, <em>복사</em> 및 <em>붙여넣기</em>를 <a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection" class="external-link">부동 도구 모음</a>으로 표시하게 됩니다.
-
- 이 사용자 상호작용 구현은 상황별 작업 모음에서와 비슷합니다. 이 내용은 <a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">각각의 보기에 대한 상황별 작업 모드의 활성화</a>에 설명되어 있습니다.
-
-
-</p>
-
-<p>텍스트 선택을 위해 부동 도구 모음을 구현하려면 기존 앱에 다음과 같은 변경을 적용하면 됩니다.
-</p>
-<ol>
-<li>{@link android.view.View} 또는 {@link android.app.Activity} 객체에서 {@link android.view.ActionMode} 호출을 {@code startActionMode(Callback)}에서 {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}로 변경합니다.
-
-</li>
-<li>기존 {@code ActionMode.Callback} 구현을 변경하여 대신 {@code ActionMode.Callback2}를 확장합니다.
-</li>
-<li>{@code Callback2.onGetContentRect()} 메서드를 재정의하여 보기에서 콘텐츠 {@link android.graphics.Rect} 객체(예: 텍스트 선택 직사각형)의 좌표를 제공합니다.
-</li>
-<li>직사각형 위치 지정이 더 이상 유효하지 않고, 무효화할 요소가 이것뿐인 경우 {@code ActionMode.invalidateContentRect()} 메서드를 호출합니다.
-</li>
-</ol>
-
-<p><a href="{@docRoot}tools/support-library/index.html">Android 지원 라이브러리</a> 수정 버전 22.2를 사용하는 경우, 부동 도구 모음은 이전 버전과 호환되지 않으며 AppCompat이 기본적으로 {@link android.view.ActionMode} 객체의 제어권을 넘겨받는다는 점을 유의하세요.
-
-
- 이렇게 하면 부동 도구 모음이 표시되지 않도록 방지합니다. {@link android.support.v7.app.AppCompatActivity}에서 {@link android.view.ActionMode}를 활성화하려면, {@code android.support.v7.app.AppCompatActivity.getDelegate()}를 호출한 다음 {@code android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled()}를 반환된 {@link android.support.v7.app.AppCompatDelegate} 객체에서 호출하고 입력 매개변수를 {@code false}로 설정하세요.
-
-
-
-
-
- 이 호출은 {@link android.view.ActionMode} 객체의 제어권을 프레임워크에 돌려줍니다.
- M 미리 보기를 실행하는 기기에서 이렇게 하면 프레임워크가 {@link android.support.v7.app.ActionBar} 또는 부동 도구 모음 모드를 지원할 수 있고, 한편 M 미리 보기 이전 기기에서는 {@link android.support.v7.app.ActionBar} 모드만 지원됩니다.
-
-</p>
-
-<h2 id="behavior-keystore">Android 키노트 변경</h2>
-<p>이 미리 보기에서는 <a href="{@docRoot}training/articles/keystore.html">Android 키노트 제공자</a>가 더 이상 DSA를 지원하지 않습니다.
-
- ECDSA는 여전히 지원됩니다.</p>
-
-<p>휴식 중일 때 암호화가 필요하지 않은 키도 보안 잠금 화면이 비활성화되거나 재설정될 때(예: 사용자가 또는 기기 관리자가 재설정) 더 이상 삭제되지 않습니다.
- 휴식 중일 때 암호화가 필요한 키는 이러한 이벤트 중에 삭제됩니다.
-</p>
-
-<h2 id="behavior-network">Wi-Fi 및 네트워킹 변경</h2>
-
-<p>이 미리 보기에서는 Wi-Fi와 네트워킹 API에 다음과 같은 동작 변경을 도입합니다.</p>
-<ul>
-<li>이제 앱이 {@link android.net.wifi.WifiConfiguration} 객체의 상태를 변경할 수 있는 것은 개발자가 이와 같은 객체를 생성한 경우뿐입니다.
- 사용자 또는 다른 앱이 생성한 {@link android.net.wifi.WifiConfiguration} 객체는 개발자가 수정하거나 삭제할 권한이 없습니다.
-
-</li>
-<li>
-이전에는 앱이 기기에 강제로 특정 Wi-Fi 네트워크에 연결하도록 하는 경우, 즉{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()}를 {@code disableAllOthers=true} 설정으로 사용하면 기기가 셀룰러 데이터와 같은 다른 네트워크에서는 연결을 해제했습니다.
-
-
- 이 미리 보기에서는 기기가 그러한 다른 네트워크에서 더 이상 연결을 해제하지 않습니다. 앱의 {@code targetSdkVersion}이 {@code “20”} 이하인 경우, 이것은 선택한 Wi-Fi 네트워크에 고정되어 있습니다.
-
- 앱의 {@code targetSdkVersion}이 {@code “21”} 이상인 경우, 멀티네트워크 API를 사용합니다(예: {@link android.net.Network#openConnection(java.net.URL) openConnection()}, {@link android.net.Network#bindSocket(java.net.Socket) bindSocket()} 및 새로운 {@code ConnectivityManager.bindProcessToNetwork()} 메서드). 이렇게 하면 네트워크 트래픽이 선택한 네트워크에서 전송되도록 보장할 수 있습니다.
-
-
-
-
-</li>
-</ul>
-
-<h2 id="behavior-camera">카메라 서비스 변경</h2>
-<p>이 미리 보기에서는 카메라 서비스에서 공유된 리소스에 액세스하는 모델이 이전의 "선착순" 액세스 모델에서 바뀌어 우선 순위가 높은 프로세스를 선호하는 액세스 모델로 변경되었습니다.
-
- 서비스 동작에 대한 변경 내용은 다음과 같습니다.</p>
-<ul>
-<li>카메라 하위 시스템 리소스(카메라 기기 열기 및 구성하기 포함)에 대한 액세스 권한은 클라이언트 애플리케이션 프로세스의 "우선 순위"를 기반으로 부여됩니다.
- 대개는 사용자에게 표시되는 액티비티 또는 전경 액티비티가 있는 애플리케이션 프로세스에 높은 우선 순위가 부여되어 카메라 리소스 획득과 사용에 좀 더 신뢰감을 더합니다.
-
-</li>
-<li>우선 순위가 낮은 앱에 대한 활성 카메라 클라이언트는 우선 순위가 더 높은 애플리케이션이 카메라를 사용하려 시도하면 "제거"될 수 있습니다.
- 사용이 중단된 {@link android.hardware.Camera} API의 경우, 이 때문에 {@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()}가 제거된 클라이언트에 대해 호출되는 결과를 초래합니다.
-
-
- {@link android.hardware.camera2 Camera2} API에서는 제거된 클라이언트에 대해 {@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}가 호출됩니다.
-
-</li>
-<li>적절한 카메라 하드웨어를 갖춘 기기에서는 별도의 애플리케이션 프로세스가 각자 따로따로 열려 동시에 각기 다른 카메라 기기를 사용할 수 있습니다.
- 하지만 여러 프로세스를 사용하는 경우 동시에 액세스하면 열려 있는 카메라 기기 모두의 성능 또는 기능이 대폭 저하되는 결과를 유발했었는데, 이런 경우도 이제 카메라 서비스가 감지하여 허용하지 않게 됩니다.
-
- 이러한 변경으로 인해, 같은 카메라 기기에 직접 액세스하려 시도하는 앱이 없는 경우에도 우선 순위가 낮은 클라이언트를 "제거"하는 결과를 초래할 수도 있습니다.
-
-
-</li>
-<li>
-현재 사용자를 변경하면 앱 내에서 이전 사용자 계정이 소유하는 활성 카메라 클라이언트를 제거하는 결과를 유발할 수 있습니다.
- 카메라에 대한 액세스는 현재 기기 사용자가 소유한 사용자 프로필에게만 국한됩니다. 이것은 실제로 예를 들면, 사용자가 다른 계정으로 전환하면 "Guest" 계정은 카메라 시스템을 사용하는 실행 중인 프로세스에서 나갈 수 없게 된다는 뜻입니다.
-
-
-</li>
-</ul>
-
-<h2 id="behavior-art-runtime">ART 런타임</h2>
-<p>이제 ART 런타임이 {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 메서드에 대한 액세스 규칙을 제대로 구현할 수 있습니다.
- 이 변경 덕분에 이전 버전에서는 Dalvik이 액세스 규칙을 잘못 확인하던 문제를 해결했습니다. 앱이 {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} 메서드를 사용하고 액세스 확인을 재정의하고자 하는 경우, {@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} 메서드를 호출하되 입력 매개변수를 {@code true}로 설정한 상태로 사용합니다.
-
-
-
-
-
- 앱이 <a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 AppCompat 라이브러리</a> 또는 <a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 RecyclerView 라이브러리</a>를 사용하는 경우, 앱을 업데이트하여 이러한 라이브러리의 최신 버전을 사용하도록 해야 합니다.
-
-
- 그렇지 않으면, XML에서 참조되는 모든 사용자 지정 클래스가 업데이트되도록 확인하여 그 클래스 생성자에 액세스할 수 있도록 해야 합니다.
-</p>
-
-<p>이 미리 보기에서는 동적 링커의 동작을 업데이트합니다. 동적 링커는 이제 라이브러리의 {@code soname}과 그 경로(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">공개 버그 6670</a>) 사이의 차이점을 숙지하고 있으며, 이제 {@code soname} 기준 검색도 구현되었습니다.
-
-
-
- 이전에 작동한 앱 중에서 {@code DT_NEEDED} 항목이 있는 경우(주로 빌드 머신의 파일 시스템에 있는 절대 경로) 로딩했을 때 실패할 수 있습니다.
-</p>
-
-<p>이제 {@code dlopen(3) RTLD_LOCAL} 플래그를 올바르게 구현했습니다. 이때 {@code RTLD_LOCAL}이 기본이므로 {@code dlopen(3)}에 대한 호출 중에서 {@code RTLD_LOCAL}을 명시적으로 사용하지 않으면 영향받을 수 있다는 점을 유의하세요(다만 앱이 명시적으로 {@code RTLD_GLOBAL}을 사용한 경우는 예외입니다).
-
- {@code RTLD_LOCAL}의 경우, 나중에 {@code dlopen(3)}으로 한 호출로 인해 로딩된 라이브러리에서는 기호를 이용할 수 없게 됩니다({@code DT_NEEDED} 항목에 의해 참조된 것과는 반대입니다).
-
-</p>
-</p>
-
-<h2 id="behavior-apk-validation">APK 유효성 검사</h2>
-<p>이제 플랫폼이 APK에 대해 좀 더 엄격한 유효성 검사를 수행합니다. APK는 파일이 매니페스트에서는 선언되었지만 APK 자체에는 없는 경우 손상된 것으로 간주됩니다.
- 콘텐츠가 하나라도 제거되면 APK를 다시 서명해야 합니다.
-</p>
-
-<h2 id="behavior-afw">Android for Work 변경</h2>
-<p>이 미리 보기에는 Android for Work에 대해 다음과 같은 동작 변경을 포함합니다.</p>
-<ul>
-<li><strong>업무용 연락처를 개인적인 맥락에서 이용.</strong> 이제 Google 다이얼러 통화 기록에서 사용자가 이전 통화 목록을 볼 때 업무용 연락처를 표시합니다. {@code DevicePolicyManager.setCrossProfileCallerIdDisabled()}를 {@code true}로 설정하면 Google 다이얼러 통화 기록에서 업무용 프로필 연락처를 숨길 수 있습니다.
-
-
- {@code DevicePolicyManager.setBluetoothContactSharingDisabled()}를 {@code false}로 설정했을 때에만 블루투스를 통해 기기에 업무용 연락처를 개인용 연락처와 함께 표시합니다.
-
- 이것은 기본적으로 {@code true}로 설정되어 있습니다.
-
-</li>
-<li><strong>WiFi 구성 제거:</strong> 프로필 소유자가 추가한 WiFi 구성(예를 들어 {@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
-addNetwork()} 메서드로의 호출을 통해)은 이제 해당 작업 프로필이 삭제되면 함께 제거됩니다.
-
-</li>
-<li><strong>WiFi 구성 잠금:</strong> 이제 활성 기기 소유자가 생성한 WiFi 구성이라면 사용자는 임의의 구성을 수정 또는 삭제할 수 없습니다.
- 사용자는 여전히 본인의 WiFi 구성을 생성하고 수정할 수 있습니다. 해당 사용자에 대해 {@link android.os.UserManager} 상수 {@link android.os.UserManager#DISALLOW_CONFIG_WIFI}가 설정되지만 않았으면 됩니다.
-
-</li>
-<li><strong>Google 계정 추가를 통해 작업 정책 컨트롤러 다운로드:</strong> 작업 정책 컨트롤러(WPC) 앱을 통해 관리해야 하는 Google 계정이 관리된 맥락을 벗어나 기기에 추가되는 경우, 이제 추가 계정 흐름이 사용자에게 메시지를 표시하여 적절한 WPC를 설치하도록 합니다. 이 동작은 최초 기기 설정 마법사의 <strong>설정 &gt; 계정</strong>을 통해서 추가되는 계정에도 적용됩니다.
-
-
-
-</li>
-<li><strong>특정 DevicePolicyManager API 동작에 적용된 변경:</strong> {@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()} 메서드를 호출하면 호출한 사용자에 대한 카메라에만 영향을 미칩니다. 이것을 관리된 프로필에서 호출하면 기본 사용자에서 실행 중인 카메라 앱에 영향을 미치지 않습니다.
-
-
- 또한, 이제 {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} 메서드를 기기 소유자뿐만 아니라 프로필 소유자에 대해서도 이용할 수 있습니다.
-
- 프로필 소유자는 다음과 같은 키가드 제한 사항을 설정할 수 있습니다.
-
-<ul>
-<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} 및 {@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}를 설정하면 프로필의 상위 사용자에 대한 키가드 설정에 영향을 미칩니다.
-
-</li>
-<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}를 설정하면 관리된 프로필에 있는 애플리케이션이 생성한 알림에만 영향을 미칩니다.
-</li>
-</ul>
-</li>
-</ul>
diff --git a/docs/html-intl/intl/ko/preview/download.jd b/docs/html-intl/intl/ko/preview/download.jd
deleted file mode 100644
index d92453ab4f5f..000000000000
--- a/docs/html-intl/intl/ko/preview/download.jd
+++ /dev/null
@@ -1,361 +0,0 @@
-page.title=다운로드
-page.image=images/cards/card-download_16-9_2x.png
-
-@jd:body
-
-<div style="position:relative; min-height:600px">
-
- <div class="wrap" id="tos" style="position:absolute;display:none;width:inherit;">
-
- <p class="sdk-terms-intro">Android 미리 보기 SDK의 구성 요소를 다운로드하고 설치하기 전에 우선 다음과 같은 사용 약관에 동의해야 합니다.
-</p>
-
- <h2 class="norule">사용 약관</h2>
-
- <div class="sdk-terms" onfocus="this.blur()" style="width:678px">
-이것은 Android SDK 미리 보기 라이선스 계약서입니다(이하 "라이선스 계약").
-
-1. 개요
-
-1.1 Android SDK 미리 보기(본 라이선스 계약에서는 "미리 보기"라고 칭하며, 구체적으로 Android 시스템 파일, 패키지 API 및 미리 보기 라이브러리 파일이 이용 가능한 경우 및 이용 가능하게 전환된 경우 이를 포함한 것을 가리킴)는 본 라이선스 계약 조건에 따라 계약자에게 사용을 허여합니다. 본 라이선스 계약은 미리 보기 사용과 관련하여 계약자와 Google 간에 법적 구속력이 있는 계약을 체결합니다.
-
-1.2 "Android"는 기기를 위한 Android 소프트웨어 스택을 의미합니다. 이는 http://source.android.com/ URL에 위치하며 수시로 업데이트되는 Android 오픈 소스 프로젝트에서 제공됩니다.
-
-1.3 "Google"은 미국 1600 Amphitheatre Parkway, Mountain View, CA 94043에 본사를 두고 있는 델라웨어주 법인인 Google Inc.를 의미합니다.
-
-2. 라이선스 계약에 동의
-
-2.1 이 미리 보기를 사용하려면, 먼저 라이선스 계약에 동의해야 합니다. 이 라이선스 계약에 동의하지 않고 미리 보기를 사용해서는 안 됩니다.
-
-2.2 수락을 클릭하고/거나 미리 보기를 사용하면 본 라이선스 계약 조건에 동의하는 것으로 간주됩니다.
-
-2.3 미국법 또는 현재 거주 중이거나 미리 보기를 사용하는 국가를 포함하여 다른 국가의 법에 따라 미리 보기를 받는 것이 금지된 경우, 미리 보기를 사용할 수 없으며 본 라이선스 계약을 수락할 수 없습니다.
-
-2.4 회사 또는 단체 내에서 내부적으로 미리 보기를 사용하며 고용주 또는 기타 단체를 대신하여 본 라이선스 계약 준수에 동의하는 경우, 계약자의 고용주나 그 단체에 본 라이선스 계약에 대한 구속력을 부여할 수 있는 모든 법적 권한을 계약자가 갖고 있음을 진술하고 보증합니다. 구속력을 부여할 수 있는 법적 권한이 없을 경우, 고용주 또는 기타 단체를 대신하여 본 라이선스 계약에 동의하거나 미리 보기를 사용할 수 없습니다.
-
-3. Google이 허하는 미리 보기 라이선스
-
-3.1 본 라이선스 계약의 조건에 따라 Google은 계약자에게 로열티 없고 양도 불가능하며 비독점적이고 2차 인가를 불허하며, 한정되고 무효화할 수 있는 미리 보기 사용 권한을 허용하여 회사 또는 조직 내에서 개인적 또는 내부적으로 사용할 수 있도록 합니다. 이는 Android 플랫폼에서 실행되는 애플리케이션을 개발할 목적으로만 사용해야 합니다.
-
-3.2 계약자는 SDK에 존재하는 지적 재산권을 포함한 SDK에 대한 모든 법적인 권리, 소유권 및 이익이 Google 또는 제3자에게 있음에 동의합니다 "지적 재산권"은 모든 특허법, 저작권법, 영업비밀법, 상표법상 존재하는 모든 권리 및 기타 모든 재산권을 의미합니다. Google은 계약자에게 명시적으로 부여하지 않은 모든 권리를 보유합니다.
-
-3.3 본 라이선스 계약에 명시적으로 허용된 용도 외에는 미리 보기를 사용할 수 없습니다. 해당 제3자 라이선스 요건이 허용하는 범위를 제외하고 계약자는 미리 보기의 일부분을 (a) 복사(백업 목적 제외), 수정, 개작, 재배포, 역컴파일, 리버스 엔지니어링, 분해하거나 이를 통해 파생물을 생성하거나 (b) 개인 컴퓨터를 제외한 모바일 단말기 또는 기타 모든 하드웨어 기기에 미리 보기의 일부를 로드하거나, 미리 보기의 일부를 다른 소프트웨어와 결합하거나 미리 보기의 일부가 통합된 일체의 소프트웨어나 기기를 배포해서는 안 됩니다.
-
-3.4 계약자는 미리 보기에서 파생된 소프트웨어 개발 키트의 배포, 이러한 키트 생성에 참여 또는 홍보를 포함하되 이에 국한되지 않고, Android의 단편화를 야기하는 어떠한 행동도 취하지 않을 것임에 동의합니다.
-
-3.5 오픈 소스 소프트웨어 라이선스에 의거한 미리 보기 구성요소의 사용, 재생산, 배포에는 본 라이선스 계약이 아닌, 해당 오픈 소스 소프트웨어 라이선스의 조건이 적용됩니다. 계약자는 허용된 모든 권한 하에서 그러한 오픈 소스 소프트웨어 라이선스에 관해 충실한 피허가자로서의 자세를 견지할 것이며 그러한 권한을 종료, 일시 중단 또는 침해하는 행위를 삼갈 것을 동의합니다.
-
-3.6 계약자는 Google이 제공하는 SDK의 형태 및 특성이 사전 통지 없이 변경될 수 있음에 동의하며, 이전 버전의 미리 보기에서 개발된 애플리케이션이 이후 버전의 SDK와 호환되지 않을 수 있음에 동의합니다. 계약자는 계약자 또는 사용자에게 사전 통지 없이 SDK(또는 SDK에 포함된 기능) 제공을(영구적 또는 일시적으로) 중단할 수 있는 권한이 Google에게 있음에 동의합니다.
-
-3.7 본 라이선스 계약은 계약자에게 Google의 상표명, 상표, 서비스 표시, 로고, 도메인 이름, 기타 독특한 브랜드 특징에 대한 사용 권한을 부여하지 않습니다.
-
-3.8 계약자는 SDK에 부착되어 있거나 포함되어 있는 모든 소유권 고지 사항(저작권 및 상표 고지 사항 포함)을 제거, 변경 또는 불분명하게 만들지 않을 것에 동의합니다.
-
-4. 계약자의 미리 보기 사용
-
-4.1 Google은 본 라이선스 계약의 어떤 조항도 계약자(또는 계약자의 사용 허가자)가 미리 보기를 사용하여 개발한 소프트웨어 애플리케이션에 대한 권리, 소유권 또는 이익, 그리고 해당 애플리케이션에 존재하는 모든 지적 재산권을 부여하지 않는다는 점에 동의합니다.
-
-4.2 계약자는 (a) 본 라이선스 계약 그리고 (b) 모든 준거법, 규정 또는 관련 관할권 내에서 일반적으로 수용되는 관행 또는 지침(미국 또는 기타 관련 국가로/에서의 데이터 또는 소프트웨어 수출과 관련된 모든 법률 포함)에서 허용하는 용도에 한하여 미리 보기를 사용하고 애플리케이션을 작성하는 것에 동의합니다.
-
-4.3 계약자는 일반 대중 사용자를 대상으로 미리 보기를 사용하여 애플리케이션을 개발하는 경우, 해당 사용자의 프라이버시 및 법적 권리를 보호하는 것에 동의합니다. 사용자가 계약자에게 사용자 이름, 비밀번호 또는 기타 로그인 정보나 개인 정보를 제공하는 경우, 계약자는 제공된 정보가 자신의 애플리케이션에 제공된다는 사실을 사용자에게 알려야 하며, 반드시 법적으로 적절한 개인정보 보호정책 고지 및 보호를 해당 사용자에게 제공해야 합니다. 애플리케이션에서 사용자가 제공한 개인정보나 민감한 정보를 저장하는 경우, 이를 안전하게 처리해야 합니다. 사용자들이 애플리케이션에 Google 계정 정보를 제공하는 경우, 애플리케이션은 해당 사용자의 Google 계정에 액세스하는 목적으로만, 그리고 각 사용자가 허용한 범위 내의 한정된 목적으로만 이러한 정보를 사용해야 합니다.
-
-4.4 계약자는 Google 또는 기타 모든 타사의 서버, 네트워크 또는 기타 모든 재산 또는 서비스를 허가 없이 방해, 교란, 손상 또는 액세스하는 애플리케이션의 개발 또는 배포를 포함한 하등의 행위에 미리 보기를 이용하지 않을 것임을 동의합니다.
-
-4.5 계약자는 자신이 Android 및/또는 Android용 애플리케이션을 통해 생성, 전송 또는 표시하는 모든 데이터, 콘텐츠 또는 리소스 그리고 그로 인한 결과(Google이 입을 수 있는 모든 피해나 손실 포함)에 대해 전적으로 책임이 있다는 것(그리고 Google은 계약자 또는 모든 제3자에 대한 책임이 없다는 것)에 동의합니다.
-
-4.6 계약자는 본 라이선스 계약, 모든 해당 제3자 계약 또는 서비스 약관, 또는 모든 준거법 또는 규정에 의거한 계약자 의무 위반, 그리고 그로 인한 결과(Google 또는 제3자가 입을 수 있는 모든 피해나 손실 포함)에 전적으로 책임이 있다는 것(그리고 Google은 계약자 또는 모든 제3자에 대한 책임이 없다는 것)에 동의합니다.
-
-4.7 이 미리 보기는 현재 개발 단계에 있으며, 계약자의 테스트와 피드백은 그러한 개발 과정에 중요한 부분을 차지합니다. 미리 보기를 사용함으로써 계약자는 일부 기능의 구현은 아직 개발 중인 상태이며 미리 보기가 안정된 릴리스처럼 완벽하게 기능할 것이라 믿고 사용해서는 안 된다는 점을 인지하는 것으로 간주합니다. 계약자는 이 미리 보기를 사용한 애플리케이션을 공개적으로 배포 또는 배송하지 않기로 동의합니다. 이 미리 보기는 공식 Android SDK가 출시된 이후에는 더 이상 지원되지 않기 때문입니다.
-
-5. 계약자의 개발자 자격 증명
-
-5.1 계약자는 Google이 발급했거나 자신이 선택한 모든 개발자 자격 증명에 대한 기밀성을 유지할 책임이 있으며 계약자의 개발자 자격 증명 하에 개발된 모든 애플리케이션에 대한 전적인 책임이 있음에 동의합니다.
-
-6. 개인정보 보호정책 및 정보
-
-6.1 미리 보기를 지속적으로 혁신하고 개선하기 위해, Google은 고유 식별자, 관련 IP 주소, 소프트웨어 버전 번호, 미리 보기에서 사용 중인 도구 및/또는 서비스와 도구의 사용법에 대한 정보를 포함하되 이에 국한되지 않고 소프트웨어에서 특정 사용량 통계 정보를 수집할 수 있습니다. 그러한 정보를 수집하기 전에 미리 보기는 계약자에게 이를 통지하고 동의를 구할 것입니다. 계약자가 동의하지 않을 경우 정보를 수집하지 않습니다.
-
-6.2 수집된 데이터는 모두 취합된 형태로 미리 보기 개선을 위해 검토되며, Google의 개인정보 보호정책에 따라 유지 관리됩니다. 이 정보는 http://www.google.com/policies/privacy/를 참조하십시오.
-
-7. 제3자 애플리케이션
-
-7.1 제3자가 개발한 애플리케이션을 실행하거나 제3자가 제공한 데이터, 콘텐츠 또는 리소스에 액세스하기 위해 미리 보기를 사용하는 경우, 계약자는 Google이 그러한 애플리케이션, 데이터, 콘텐츠 또는 리소스에 대한 책임이 없음에 동의합니다. 계약자는 그러한 제3자 애플리케이션을 통해 자신이 액세스한 모든 데이터, 콘텐츠 또는 리소스에 대한 책임은 그것을 만든 사람에게 있음에 동의합니다. 또한 계약자가 그러한 모든 제3자 애플리케이션, 데이터, 콘텐츠 또는 리소스를 사용하거나 액세스함으로써 비롯된 모든 피해나 손실에 대한 책임이 Google에게 없음에 동의합니다.
-
-7.2 그러한 제3자 애플리케이션을 통해 계약자에게 제공된 데이터, 콘텐츠 그리고 리소스는 그것을 제공한 제공자(또는 제공자를 대신하는 기타 개인 또는 기업)가 소유한 지적 재산권에 의해 보호될 수 있음을 유의해야 합니다. 그러한 데이터, 콘텐츠 또는 리소스(전부 또는 일부)를 수정, 임대, 리스, 대여, 판매, 배포하거나 이를 기반으로 파생물을 생성해서는 안 됩니다. 단, 관련 소유자로부터 그러한 작업을 수행해도 좋다는 허락을 받은 경우에는 예외입니다.
-
-7.3 계약자는 그러한 제3자 애플리케이션, 데이터, 콘텐츠 또는 리소스의 사용은 계약자와 관련 제3자 간에 체결하는 별도의 계약 조건의 적용을 받는다는 것을 인정합니다.
-
-8. Google API 사용
-
-8.1 Google Data API
-
-8.1.1 Google에서 데이터를 검색하기 위해 API를 사용하는 경우, 그러한 데이터가 Google 또는 데이터를 제공하는 당사자(또는 당사자를 대신하는 기타 개인 또는 기업)가 소유한 지적 재산권에 의해 보호될 수 있음을 인정합니다. 그러한 API를 사용하는 경우, 추가적인 서비스 약관의 적용을 받을 수 있습니다. 관련 서비스 약관에 허용되지 않은 한, 그러한 데이터(전부 또는 일부)를 변경, 임대, 리스, 대여, 판매, 배포하거나 이를 기반으로 파생물을 생성해서는 안 됩니다.
-
-8.1.2 Google에서 사용자 데이터를 검색하기 위해 API를 사용하는 경우, 계약자는 사용자로부터 명시적인 동의를 얻은 경우에 한하여, 그리고 해당 사용자가 허용한 범위 내의 한정된 목적으로만 데이터를 검색해야 합니다.
-
-9. 라이선스 계약 종료
-
-9.1 본 라이선스 계약은 계약자 또는 Google에 의해 아래와 같은 조건 하에 종료될 때까지 계속 적용됩니다.
-
-9.2 계약자가 라이선스 계약을 종료하고자 하는 경우, 미리 보기 및 관련 개발자 자격 증명 일체의 사용을 중단하는 것으로 그러한 의사를 피력할 수 있습니다.
-
-9.3 Google은 언제든 이유 여하를 불문하고 계약자에게 통고하여 라이선스 계약을 종료할 수 있습니다.
-
-9.4 본 라이선스 계약은 통보 또는 여타의 행위 없이도 자동으로 종료됩니다. 이에 해당되려면 다음과 같은 조건이 수반되어야 합니다.
-(A) Google이 계약자가 거주하는 국가 또는 계약자가 서비스를 사용하는 지역에서 미리 보기 또는 미리 보기의 특정 부분 제공을 중지하는 경우 및
-(B) Google이 Android SDK의 최종 릴리스 버전을 발행하는 경우.
-
-9.5 본 라이선스 계약이 종료되면 라이선스 계약으로 계약자에게 허용한 라이선스가 취소되며, 이에 따라 계약자는 미리 보기 사용을 즉시 모두 중단해야 하고 제 10, 11, 12 및 14절의 조항이 기한 없이 유지됩니다.
-
-10. 면책 조항
-
-10.1 계약자는 미리 보기 이용에 대한 위험 부담이 전적으로 본인에게 있으며, Google이 일체의 보증 없이 미리 보기를 "있는 그대로" 그리고 "이용 가능한" 상태로 제공한다는 것을 분명히 이해하고 동의합니다.
-
-10.2 미리 보기 이용 및 이용 과정에서 다운로드하거나 얻게 되는 모든 자료를 사용하는 것은 본인의 재량에 따르며 이에 대한 위험 부담이 전적으로 본인에게 있으며, 그러한 사용으로 인해 발생하는 컴퓨터 시스템 또는 다른 기기의 손상 또는 데이터 손실에 대한 책임은 전적으로 본인에게 있습니다. 전술한 조항을 제한하지 않는 범위 내에서 계약자는 미리 보기가 안정된 릴리스가 아니며 오류, 결함 및 보안 취약성이 포함되어 있을 수 있어 그 결과로 중대한 손상을 유발할 수 있다는 점을 이해하는 것으로 간주합니다. 여기에는 계약자의 컴퓨터 시스템 또는 기타 기기의 완전하고 돌이킬 수 없는 손실도 포함됩니다.
-
-10.3 더 나아가, Google은 상품성, 특정 목적에 대한 적합성 및 비침해의 묵시적 보증 등을 포함하되 이에 국한되지 않고 명시적이든 묵시적이든 모든 종류의 보증 및 조건을 명시적으로 부인합니다.
-
-11. 책임 한계
-
-11.1 계약자는 계약자에게 발생할 수 있는 직접, 간접, 부수적, 특별, 결과적 또는 징벌적 손해에 대해 그 어떤 책임 이론에 근거해서도 Google, 해당 자회사, 계열사 및 사용 허가자가 어떠한 책임도 지지 아니함을 분명히 이해하고 동의합니다. 이러한 손해에는 Google 또는 해당 대리자가 이러한 손실 발생 가능성에 대해 통지를 받았거나 이러한 사항을 인식했는지에 상관없이 모든 데이터 손실이 포함됩니다.
-
-12. 면책
-
-12.1 법률에 의해 허용되는 최대한의 범위 안에서 계약자는 (a) 미리 보기 사용, (b) 계약자가 미리 보기에서 개발한 일체의 애플리케이션에서 초래된 모든 사람의 저작권, 상표, 영업비밀, 트레이드 드레스, 특허 또는 기타 지적 재산권의 침해, 또는 어떤 사람의 명예를 훼손하거나 초상권 또는 개인정보 보호정책을 침해함 또는 (C)계약자 본인이 본 라이선스 계약을 위반함으로써 발생하거나 생기는 모든 청구, 조치, 소송 또는 절차, 그리고 모든 손실, 책임, 손해, 경비(합리적인 변호사 비용 포함)로부터 Google을 옹호하고, 면책시키고, Google이 손해를 입지 않도록 하는 데 동의합니다.
-
-13. 라이선스 계약 변경
-
-13.1 미리 보기의 새로운 버전을 배포할 때, Google은 본 라이선스 계약의 내용을 변경할 수 있습니다. 그러한 변경이 이뤄진 경우, Google은 미리 보기가 제공되는 웹사이트에 새로운 라이선스 계약 버전을 게재할 것입니다.
-
-14. 일반 법적 조건
-
-14.1 본 라이선스 계약은 계약자와 Google 간의 모든 법적 계약을 구성하며, 계약자의 미리 보기 사용을 규제하고(별도의 서면 계약을 통해 Google이 계약자에게 제공하는 모든 서비스는 제외), 미리 보기와 관련하여 이전에 계약자와 Google이 맺은 모든 계약을 완전히 대체합니다.
-
-14.2 계약자는 Google이 라이선스 계약에 포함된(또는 관련 법률에 의해 Google이 향유하는) 법적 권리 또는 구제수단을 행사하거나 집행하지 않더라도, Google이 권리를 공식적으로 포기한 것으로 간주하지 않으며, Google이 계속해서 그러한 권리 또는 구제수단을 이용할 수 있음에 동의합니다.
-
-14.3 본 라이선스 계약의 조항이 무효라고 이 사안에 관한 판결을 할 수 있는 관할권을 가진 법원이 판결할 경우, 그 조항은 라이선스 계약의 나머지 조항에 영향을 미치지 않는 형태로 라이선스 계약에서 제거됩니다. 본 라이선스 계약의 나머지 조항은 여전히 유효하며 집행 가능합니다.
-
-14.4 계약자는 Google이 모회사가 되는 회사 그룹에 속한 각 회사가 본 라이선스 계약의 제3수익자이며, 그러한 다른 회사들이 그들에게 이익(또는 유리한 권리)을 부여하는 본 라이선스 계약의 모든 조항을 직접 행사하고 적용할 수 있는 권리를 가진다는 데 동의합니다. 그 외에는 다른 어떤 개인이나 회사도 본 라이선스 계약의 제3수익자가 될 수 없습니다.
-
-14.5 수출 규제. 미리 보기는 미국의 수출법과 규정의 적용을 받습니다. 계약자는 미리 보기에 적용되는 모든 국내 및 국제 수출법과 규정을 준수해야 합니다. 그러한 법에는 수출 대상국, 최종 사용자 및 최종 용도에 대한 제한이 포함됩니다.
-
-14.6 계약자 또는 Google은 상대 당사자의 사전 서면 승인 없이 본 라이선스 계약에서 부여된 권리를 제3자에게 양도하거나 이전할 수 없으며, 그러한 승인 없이 이루어진 양도 시도는 모두 무효입니다. 계약자는 Google의 사전 승인 없이 본 라이선스 계약 상의 책임 또는 의무를 위임할 수 없습니다.
-
-14.7 본 라이선스 계약, 그리고 본 라이선스 계약 상의 계약자와 Google의 관계는 법률 조항 간의 충돌과는 무관하게 캘리포니아주법에 의한 규제를 받습니다. 계약자와 Google은 본 라이선스 계약으로부터 발생하는 모든 법적 문제 해결을 캘리포니아주 산타 클라라(Santa Clara) 카운티 내에 소재한 전속 관할 법원에 의뢰하는 것에 동의합니다. 위 규정에도 불구하고, 계약자는 Google이 여전히 모든 관할권에서 강제 구제책(또는 동등한 유형의 긴급 법적 구제)을 신청할 수 있음에 동의합니다.
- </div><!-- sdk terms -->
-
-
-
- <div id="sdk-terms-form">
- <p>
- <input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" />
- <label id="agreeLabel" for="agree">본인은 상기 사용 약관을 읽었으며 이에 동의합니다.</label>
- </p>
- <p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p>
- </div>
-
-
- </div><!-- end TOS -->
-
-
- <div id="landing">
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#sdk">Android 6.0 SDK</a></li>
- <li><a href="#docs">개발자 관련 문서</a></li>
- <li><a href="#images">하드웨어 시스템 이미지</a></li>
- </ol>
-
- <h2>Legacy downloads</h2>
- <ol>
- <li><a href="{@docRoot}preview/download_mp1.html">Developer Preview 1</a></li>
- <li><a href="{@docRoot}preview/download_mp2.html">Developer Preview 2</a></li>
- </ol>
- </div>
-</div>
-
-
-<p>
- Android M 미리 보기 SDK에는 개발 도구, Android 시스템 파일 및 라이브러리 파일이 포함되어 있어 앱을 테스트하고 플랫폼의 다음 릴리스에 도입되는 새 API를 테스트하는 데 유용합니다.
- 이 문서에서는 미리 보기의 다운로드할 수 있는 구성 요소를 가져와 앱을 테스트하는 방법에 대해 설명합니다.
-
-</p>
-
-
-<h2 id="sdk">Android 6.0 SDK</h2>
-
-<p>
- 미리 보기 SDK는 <a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>를 통해 다운로드할 수 있습니다. 미리 보기 SDK를 다운로드하고 구성하는 데 관한 자세한 정보는 <a href="{@docRoot}preview/setup-sdk.html#downloadSdk">미리 보기 SDK 설정하기</a>를 참조하십시오.
-
-</p>
-
-
-<h2 id="docs">개발자 관련 문서</h2>
-
-<p>
- 개발자 관련 문서 다운로드 패키지에서는 자세한 API 참조 정보와 미리 보기에 대한 API 차이점 보고서를 제공합니다.
-</p>
-
-<table>
- <tr>
- <th scope="col">Description</th>
- <th scope="col">Download / Checksums</th>
- </tr>
- <tr id="docs-dl">
- <td>Android M Preview 3<br>Developer Docs</td>
- <td><a href="#top" onclick="onDownload(this)"
- >m-preview-3-developer-docs.zip</a><br>
- MD5: d99b14b0c06d31c8dfecb25072654ca3<br>
- SHA-1: 9cefeeda07676130da606a1796e1c00fffc667c1
- </td>
- </tr>
-</table>
-
-
-<h2 id="images">하드웨어 시스템 이미지</h2>
-
-<p>
- 이러한 시스템 이미지를 사용하면 물리적인 기기에서 플랫폼의 미리 보기 버전을 설치하여 테스트할 수 있게 해줍니다.
- 이러한 이미지 중 한 가지로 기기를 구성하면, 앱을 설치하고 테스트하여 앱이 플랫폼의 다음 버전에서 어떤 성능을 보일지 확인할 수 있습니다.
- 기기에 시스템 이미지를 설치하는 과정은<em>기기에서 모든 데이터를 제거하므로</em>, 시스템 이미지를 설치하기에 앞서 데이터를 백업하는 것이 좋습니다.
-
-
-</p>
-
-<p class="warning">
- <b>경고:</b> 다음 Android 시스템 이미지는 미리 보기이며 사정에 따라 변동될 수 있습니다. 이러한 시스템 이미지를 사용할 때에는 Android SDK 미리 보기 라이선스 계약을 따라야 합니다.
- Android 미리 보기 시스템 이미지는 안정된 릴리스가 아니며, 오류나 결함이 들어있을 수 있고 이 때문에 컴퓨터 시스템, 기기 및 데이터에 손상을 초래할 수 있습니다.
-
- 미리 보기 Android 시스템 이미지는 공장 OS와 같은 테스트를 거치며 전화기 및 설치된 서비스와 애플리케이션의 작동이 중단되는 결과를 낳을 수 있습니다.
-
-
-</p>
-
-<table>
- <tr>
- <th scope="col">Device</th>
- <th scope="col">Download / Checksums</th>
- </tr>
- <tr id="hammerhead">
- <td>Nexus 5 (GSM/LTE) <br>"hammerhead"</td>
- <td><a href="#top" onclick="onDownload(this)"
- >hammerhead-MPA44I-preview-2ebbc049.tgz</a><br>
- MD5: 91a924fb0c9f8e716e3b4c9954fd0dbb<br>
- SHA-1: 2ebbc049b68c4da8baeee3e42bb94d7a965ba4a3
- </td>
- </tr>
- <tr id="shamu">
- <td>Nexus 6 <br>"shamu"</td>
- <td><a href="#top" onclick="onDownload(this)"
- >shamu-MPA44I-preview-62b9c486.tgz</a><br>
- MD5: ac6e58da86125073d9c395257fd42664<br>
- SHA-1: 62b9c486fd7a5020e228d53ca5acd5c1857e48ff
- </td>
- </tr>
- <tr id="volantis">
- <td>Nexus 9 <br>"volantis"</td>
- <td><a href="#top" onclick="onDownload(this)"
- >volantis-MPA44I-preview-5c30a6e2.tgz</a><br>
- MD5: 7f83768757913d3fea945a661020d185<br>
- SHA-1: 5c30a6e2acd11a81f4105b12d23ff654f534f699
- </td>
- </tr>
-
- <tr id="fugu">
- <td>Nexus Player <br>"fugu"</td>
- <td><a href="#top" onclick="onDownload(this)"
- >fugu-MPA44I-preview-2860040a.tgz</a><br>
- MD5: 438da8d37da9e341a69cfb16a4001ac5<br>
- SHA-1: 2860040a326582f1ff5f702bf9a1ef002717fc98
- </td>
- </tr>
-
-</table>
-
-<h3 id="install-image">기기에 이미지 설치</h3>
-
-<p>
- 기기 이미지를 테스트용으로 사용하려면, 이를 호환되는 기기에 설치해야만 합니다. 시스템 이미지를 설치하려면 아래의 지침을 따르십시오.
-
-</p>
-
-<ol>
- <li>여기 목록에 나열된 시스템 이미지 중 하나를 다운로드하여 압축을 해제합니다.</li>
- <li>기기에서 보존하고자 하는 데이터를 모두 백업합니다.</li>
- <li>이미지를 기기에 플래시하려면 <a href="https://developers.google.com/android/nexus/images#instructions">developers.google.com/android</a>에 있는 지침을 따릅니다.
-
-</li>
-</ol>
-
-<p class="note">
- <strong>참고:</strong> 일단 개발 기기에 미리 보기 시스템 이미지를 플래시하고 나면 이것은 OTA(over-the-air) 업데이트를 통해 다음 미리 보기 릴리스에 맞춰 자동으로 업그레이드됩니다.
-
-</p>
-
-<h3 id="revertDevice">기기를 공장 사양으로 되돌리기</h3>
-
-<p>
- 미리 보기의 설치를 제거하고 기기를 공장 사양으로 되돌리고자 하는 경우, <a href="http://developers.google.com/android/nexus/images">developers.google.com/android</a>를 방문하여 기기에 플래시하고자 하는 이미지를 다운로드하십시오.
-
- 해당 페이지에 있는 지침을 따라 기기에 이미지를 플래시하면 됩니다.
-
-</p>
-
- </div><!-- landing -->
-
-</div><!-- relative wrapper -->
-
-
-
-<script>
- var urlRoot = "http://storage.googleapis.com/androiddevelopers/shareables/preview/";
- function onDownload(link) {
-
- $("#downloadForRealz").html("Download " + $(link).text());
- $("#downloadForRealz").attr('href', urlRoot + $(link).text());
-
- $("#tos").fadeIn('fast');
- $("#landing").fadeOut('fast');
-
- return true;
- }
-
-
- function onAgreeChecked() {
- /* verify that the TOS is agreed */
- if ($("input#agree").is(":checked")) {
- /* reveal the download button */
- $("a#downloadForRealz").removeClass('disabled');
- } else {
- $("a#downloadForRealz").addClass('disabled');
- }
- }
-
- function onDownloadForRealz(link) {
- if ($("input#agree").is(':checked')) {
- /*
- $("#tos").fadeOut('fast');
- $("#landing").fadeIn('fast');
- */
-
- ga('send', 'event', 'M Preview', 'System Image', $("#downloadForRealz").html());
-
- /*
- location.hash = "";
- */
- return true;
- } else {
- return false;
- }
- }
-
- $(window).hashchange( function(){
- if (location.hash == "") {
- location.reload();
- }
- });
-
-</script>
diff --git a/docs/html-intl/intl/ko/preview/features/app-linking.jd b/docs/html-intl/intl/ko/preview/features/app-linking.jd
deleted file mode 100644
index 0e23801b5b43..000000000000
--- a/docs/html-intl/intl/ko/preview/features/app-linking.jd
+++ /dev/null
@@ -1,123 +0,0 @@
-page.title=앱 링크
-page.image=images/cards/card-app-linking_2x.png
-page.keywords=applinking, 딥 링크, 인텐트
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#web-assoc">웹사이트 연관 선언</a></li>
- <li><a href="#verfy-links">앱 링크 확인 요청</a></li>
- <li><a href="#user-manage">앱 링크 설정 관리</a></li>
- </ol>
- </div>
-</div>
-
-<p>
- Android 인텐트 시스템은 유연한 메커니즘이라 앱이 콘텐츠와 요청을 처리할 수 있습니다.
- 여러 개의 앱이 자신의 인텐트 필터에서 모두 일치하는 URI 패턴을 선언할 수 있습니다. 사용자가 기본 시작 처리자가 없는 웹 링크를 클릭하는 경우 플랫폼이 대화창을 표시하여 해당 사용자가 일치하는 인텐트 필터를 선언한 앱 목록에서 선택 할 수 있습니다.
-
-
-</p>
-
-<p>
- Android M 개발자 미리 보기에서는 앱 링크에 대한 지원을 도입합니다. 이를 통해 앱 개발자들이 앱을 본인이 소유한 웹 도메인과 연관시켜 기존의 링크 처리를 한 단계 개선합니다.
- 개발자가 이 연관 관계를 생성하면 플랫폼이 특정 웹 링크를 처리하는 데 사용된 기본 앱을 알아서 판단하여 사용자에게 물어보는 과정을 건너뛸 수 있습니다.
-
-
-</p>
-
-
-<h2 id="web-assoc">웹사이트 연관 선언</h2>
-
-<p>
- 웹사이트 소유자가 앱 링크를 설정하려면 앱과의 연관 관계를 선언해야 합니다. 사이트 소유자는 앱에 대한 이러한 관계를 선언하는 데 JSON 파일을 호스팅하는 방식을 씁니다. 일명 {@code statements.json}이라는 파일을 도메인에서 잘 알려진 위치에 선언합니다.
-
-
-</p>
-
-<pre>http://&lt;domain&gt;:&lt;optional port&gt;/.well-known/statements.json</pre>
-
-<p class="note">
- <strong>참고:</strong>
- M 개발자 미리 보기 기간 중에는 JSON 파일을 http 프로토콜을 통해 확인합니다. 플랫폼이 공식적으로 출시되면 이 파일을 암호화된 https 프로토콜에서 확인하게 됩니다.
-
-</p>
-
-<p>
- 이 JSON 파일은 이 도메인 아래에서 URL에 대한 기본 처리자로 사용되어야 하는 Android 앱을 나타냅니다.
- 이것이 앱을 식별하는 기반은 다음과 같은 필드입니다.
-</p>
-
-<ul>
- <li>{@code package_name}: 앱의 매니페스트에 선언된 패키지 이름입니다.</li>
-
- <li>{@code sha256_cert_fingerprints}: 앱의 서명 인증서의 SHA256 지문입니다.
- Java keytool을 사용하여 이 지문을 생성하려면 다음과 같은 명령을 사용십시오.
- <pre>keytool -list -v -keystore my-release-key.keystore</pre>
- </li>
-</ul>
-
-<p>
- 다음 파일 목록은
-{@code statements.json} 파일의 콘텐츠와 형식을 예를 들어 나타낸 것입니다.
-</p>
-
-<pre>
-[{
- "relation": ["delegate_permission/common.handle_all_urls"],
- "target": {
- "namespace": "android_app",
- "package_name": "<strong>&lt;package name&gt;</strong>",
- "sha256_cert_fingerprints": ["<strong>6C:EC:C5:0E:34:AE....EB:0C:9B</strong>"]
- }
-}]
-</pre>
-
-
-<h2 id="verfy-links">앱 링크 확인 요청</h2>
-
-<p>
- 앱은 플랫폼에 자신의 인텐트 필터의 데이터 요소 내에서 호스트 이름으로 정의된 모든 앱 링크를 자동으로 확인해달라고 요청할 수 있습니다. 이때 비교 대상은 각각의 웹 도메인에서 호스팅된 {@code statements.json} 파일입니다.
-
- 앱 링크 확인을 요청하려면 매니페스트에서 원하는 인텐트 필터 각각에 {@code android:autoVerify}
-특성을 하나씩 추가하면 됩니다. 다음 매니페스트 코드 조각에 나타낸 내용을 참고하십시오.
-
-</p>
-
-<pre>
-&lt;activity ...&gt;
- &lt;intent-filter <strong>android:autoVerify="true"</strong>&gt;
- &lt;action android:name="android.intent.action.VIEW" /&gt;
- &lt;category android:name="android.intent.category.DEFAULT" /&gt;
- &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
- &lt;data android:scheme="http" android:host="www.android.com" /&gt;
- &lt;data android:scheme="https" android:host="www.android.com" /&gt;
- &lt;/intent-filter&gt;
-&lt;/activity&gt;
-</pre>
-
-<p>
- 앱 매니페스트에 {@code android:autoVerify} 특성이 있으면, 플랫폼은 앱이 설치된 시점에 앱 링크를 확인하려 시도합니다.
- 플랫폼이 앱 링크를 성공적으로 확인하지 못하면 해당 앱은 웹 링크를 처리하기 위한 기본 설정 앱으로 설정되지 않습니다.
- 다음번에 사용자가 그런 링크 중 하나를 열면, 플랫폼은 사용자에게 메시지를 표시하는 방식으로 변경합니다.
-
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> 테스트 중에는 확인에 실패하고 나서 거짓 긍정 결과가 나올 가능성이 있지만, 사용자가 앱에 물어보지 않고 지원되는 링크를 열도록 명시적으로 활성화해 놓았고 이때 시스템 설정 앱을 사용한 경우, 대화창이 표시되지 않고 링크는 개발자 본인의 앱으로 이동하지만 이는 순전히 사용자 설정 때문이고 확인이 성공해서가 아닙니다.
-
-
-
-</p>
-
-
-<h2 id="user-manage">앱 링크 설정 관리</h2>
-
-<p>
- 사용자가 앱 링크 설정을 변경하여 URL을 본인이 선호하는 방식으로 처리하도록 할 수 있습니다. 앱 링크를 검토하고 관리하려면 <strong>설정 &gt; 앱 &gt; 앱 정보 &gt; 기본으로 열기</strong> 아래의 시스템 설정 앱에서 하면 됩니다.
-
-
-</p>
diff --git a/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd b/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
deleted file mode 100644
index 20c52329aa69..000000000000
--- a/docs/html-intl/intl/ko/preview/features/runtime-permissions.jd
+++ /dev/null
@@ -1,794 +0,0 @@
-page.title=권한
-page.tags=previewresources, androidm
-page.keywords=권한, 런타임, 미리 보기
-page.image={@docRoot}preview/features/images/permissions_check.png
-@jd:body
-
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>간략히 보기</h2>
- <ul>
- <li>앱이 M 미리 보기 SDK를 대상으로 하는 경우, 앱은 사용자에게 설치 시점이 아닌 런타임에 권한을 허용하도록 메시지를 표시합니다.
-</li>
- <li>사용자는 앱 설정 화면에서 언제든 권한을 취소할 수 있습니다.
-</li>
- <li>앱은 실행될 때마다 자신에게 필요한 권한이 있는지 확인해야 합니다.
-</li>
- </ul>
-
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#overview">개요</a></li>
- <li><a href="#coding">런타임 권한에 대한 코딩</a></li>
- <li><a href="#testing">런타임 권한 테스트</a></li>
- <li><a href="#best-practices">모범 사례</a></li>
- </ol>
-
-<!--
- <h2>Related Samples</h2>
- <ol>
- <li></li>
- </ol>
--->
-
-<!--
- <h2>See also</h2>
- <ol>
- <li></li>
- </ol>
--->
- </div> <!-- qv -->
-</div> <!-- qv-wrapper -->
-
-
-<p>
- M 개발자 미리 보기에서는 새로운 앱 권한 모델을 소개하여 사용자가 앱을 설치하고 업그레이드하는 과정을 간소화할 수 있습니다.
- M 미리 보기에서 실행되는 앱이 새 권한 모델을 지원하는 경우, 사용자가 앱을 설치하거나 업그레이드할 때 아무런 권한을 허용하지 않아도 됩니다. 그 대신, 앱이 필요할 때마다 권한을 요청하고 시스템이 사용자에게 해당 권한을 요청하는 대화창을 표시합니다.
-
-
-
-
-</p>
-
-<p>
- 앱이 새 권한 모델을 지원하는 경우, Android 이전 버전을 실행하는 기기에서도 설치 및 실행할 수 있는 것은 변하지 않습니다. 이 경우, 그러한 기기의 기존 권한 모델을 사용합니다.
-
-
-</p>
-
-<h2 id="overview">
- 개요
-</h2>
-
-<p>
- M 개발자 미리 보기에서는 플랫폼에 새로운 권한 모델을 도입합니다.
- 이 새로운 모델의 주요 구성 요소를 다음과 같이 요약해 보았습니다.
-</p>
-
-<ul>
- <li>
- <strong>권한 선언:</strong> 이전 Android 플랫폼에서와 같이 앱은 자신이 필요로 하는 권한을 모두 매니페스트에서 선언합니다.
-
- </li>
-
- <li>
- <strong>권한 그룹:</strong> 권한은 각자의 기능을 기반으로 <em>권한 그룹</em>으로 나뉩니다.
- 예를 들어 <code>CONTACTS</code> 권한 그룹에는 사용자의 연락처와 프로필 정보를 읽고 쓰는 데 필요한 권한이 들어있습니다.
-
-
- </li>
-
- <li>
- <p><strong>설치 시점에 제한된 권한 허용:</strong> 사용자가 앱을 설치 또는 업데이트하면 시스템이 해당 앱에 앱이 요청하는 권한 중 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}에 포함되는 것을 모두 허용합니다.
-
-
-
- 예를 들어 알람 시계와 인터넷 권한은 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}에 속하므로 이들 권한은 설치 시점에 자동으로 허용됩니다.
-
-
- </p>
-
- <p>시스템은 이외에도 앱 서명과 시스템 권한을 허용할 수도 있습니다. 이 내용은 <a href="#system-apps">시스템 앱 및 서명 권한</a>에 설명되어 있습니다.
-
- 설치 시 사용자에게 권한을 허용하라는 메시지가 표시되지 <em>않습니다.</em>
-</p>
- </li>
-
- <li>
- <strong>사용자가 런타임에 권한 허용:</strong> 앱이 권한을 요청하면, 시스템이 사용자에게 대화창을 표시한 다음 앱의 콜백 기능을 호출해 권한이 허용되었는지를 알려줍니다.
-
- 사용자가 권한을 허용하는 경우, 앱에는 앱 매니페스트에서 선언한 해당 권한의 기능 영역에 관한 모든 권한이 부여됩니다.
-
-
- </li>
-
-</ul>
-
-<p>
- 이 권한 모델은 앱이 권한을 필요로 하는 기능에 대해 동작하는 방식을 바꾸어 놓습니다.
- 다음은 이 모델에 적응하기 위한 몇 가지 개발 사례를 요약했습니다.
-
-</p>
-
-<ul>
-
- <li>
- <strong>항상 권한을 확인:</strong> 앱이 권한을 필요로 하는 작업을 수행해야 할 때마다, 우선 앱에 해당 권한이 있는지 확인해야 합니다.
-
- 권한이 없는 경우, 해당 권한을 허용해도록 요청합니다.
-
- </li>
-
- <li>
- <strong>권한 부족을 안정적으로 처리:</strong> 앱이 적절한 권한을 허용받지 못하면, 실패를 깔끔하게 처리할 수 있어야 합니다.
-
- 예를 들어 권한에 기능만 추가하면 되는 것이었다면, 앱이 해당 기능을 비활성화하면 됩니다.
- 해당 권한이 앱이 제대로 기능하는 데 꼭 필요한 것이라면, 앱이 자신의 기능을 모두 비활성화하고 사용자에게 그 권한을 허용해야 한다고 알릴 수도 있습니다.
-
-
- </li>
-
- <div class="figure" style="width:220px" id="fig-perms-screen">
- <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220">
- <p class="img-caption">
- <strong>그림 1.</strong> 앱의 '설정'에 있는 권한 화면.
- </p>
- </div>
-
- <li>
- <strong>취소 가능한 권한:</strong> 사용자는 언제든 앱의 권한을 취소할 수 있습니다.
- 사용자가 앱의 권한을 끄면 해당 앱에 그 사실을 알리지 <em>않습니다.</em>
- 이런 경우, 앱이 제한된 작업을 수행하려면 필요한 권한이 있다는 점을 다시 확인해야 합니다.
-
- </li>
-</ul>
-
-<p class="note">
- <strong>참고:</strong> 앱이 M 개발자 미리 보기를 대상으로 하는 경우, <em>반드시</em> 새 권한 모델을 사용해야 합니다.
-
-</p>
-
-<p>
- M 개발자 미리 보기 시작 시점에는 Google 앱 중에 새 권한 모델을 완전히 구현하지 않는 앱도 있습니다.
- Google은 이러한 앱을 M 개발자 미리 보기를 시행하면서 시간을 두고 업데이트하여 권한 설정/해제 설정을 제대로 사용하도록 할 예정입니다.
-
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> 앱에 자체 API 표면이 있는 경우, 권한을 대리로 허가하기 전에 우선 발신자에게 해당 데이터에 액세스할 필수 권한이 있는지 확인해야 합니다.
-
-
-</p>
-
-<h3 id="system-apps">
- 시스템 앱 및 서명 권한
-</h3>
-
-<p>
- 보통 사용자가 앱을 설치하면 시스템이 앱에 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}만 허용합니다.
-
- 하지만 시스템이 앱에 더 많은 권한을 허용하는 경우도 몇 가지 있습니다.
-
-</p>
-
-<ul>
- <li>앱이 시스템 이미지의 일부분인 경우, 이 앱의 매니페스트에 목록으로 표시된 권한을 자동으로 모두 허용합니다.
-
- </li>
-
- <li>앱이 매니페스트에서 권한을 요청했는데 그것이 {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE}에 속하며 해당 앱이 그러한 권한을 선언한 앱과 같은 인증서로 서명되어 있는 경우, 시스템은 요청하는 앱을 설치할 때 그러한 권한을 허용합니다.
-
-
-
-
- </li>
-</ul>
-
-<p>
- 두 가지 경우 모두, 사용자가 언제든 권한을 취소할 수 있는 것은 변하지 않습니다. 시스템의 <strong>설정</strong> 화면으로 이동하여 <strong>앱 &gt;</strong>
-
- <i>app_name</i> <strong>&gt; 권한</strong>을 선택하면 됩니다. 이 앱은 계속해서 런타임에 권한을 확인하고 필요한 경우 해당 권한을 요청해야 합니다.
-
-
-</p>
-
-<h3 id="compatibility">
- 이전 및 이후 버전과의 호환성
-</h3>
-
-<p>
- 앱이 M 개발자 미리 보기를 대상으로 하지 않더라도, 앱은 M 미리 보기 기기에서도 기존 권한 모델을 계속 사용합니다.
- 사용자가 앱을 설치하면 시스템이 사용자에게 앱의 매니페스트에 목록으로 표시된 권한을 모두 허용하도록 요청합니다.
-
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> M 개발자 미리 보기를 실행하는 기기에서는 사용자가 어느 앱에 대해서든(레거시 앱 포함) 앱의 설정 화면에서 권한을 끌 수 있습니다.
-
- 사용자가 레거시 앱에 대한 권한을 끄면, 시스템이 자동으로 적절한 기능을 비활성화합니다.
- 앱이 해당 권한을 필요로 하는 작업을 수행하려 시도한다고 해도 그 작업이 반드시 예외를 발생시키는 것은 아닙니다.
-
- 그 대신에 빈 데이터 세트를 반환하거나 오류를 신호하거나, 기타 예기치 못한 동작을 선보일 수 있습니다.
- 예를 들어 권한 없이 캘린더를 쿼리하면 해당 메서드가 빈 데이터 세트를 반환합니다.
-
-</p>
-
-<p>
- M 미리 보기를 실행하지 않는 기기에서 새 권한 모델을 사용하는 앱을 설치하면 시스템은 해당 앱을 다른 앱과 똑같이 다룹니다. 즉, 설치 시점에 시스템에 사용자에게 선언된 권한 모두를 허용하도록 요청합니다.
-
-
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> 미리 보기 릴리스에서는 최소 SDK 버전을 M 미리 보기 SDK로 설정해야 미리 보기 SDK와 컴파일할 수 있습니다.
- 즉, 개발자 미리 보기 시행 중에는 그러한 앱을 기존 플랫폼에서 테스트할 수 없다는 뜻입니다.
-
-
-</p>
-
-<h3 id="perms-vs-intents">권한과 인텐트 비교</h3>
-
-<p>
- 대부분의 경우, 앱에게 어떤 작업을 수행하도록 하려면 두 가지 방식 중 하나를 선택할 수 있습니다.
- 첫째로 앱이 작업을 직접 수행하도록 권한을 요청할 수 있습니다.
- 또는, 앱에 인텐트를 사용하도록 하여 또 다른 앱이 해당 작업을 수행하도록 할 수 있습니다.
-
-</p>
-
-<p>
- 예를 들어 앱이 기기 카메라로 사진을 촬영할 수 있어야 한다고 가정합시다.
- 그러면 앱은 <code>android.permission.CAMERA</code> 권한을 요청할 수 있습니다. 이렇게 하면 앱이 카메라에 직접 액세스할 수 있습니다.
-
- 그런 다음 앱이 카메라 API를 사용하여 카메라를 제어하고 사진을 촬영합니다.
- 이 방식을 사용하면 앱에 사진 촬영 과정에 대해 완전한 제어권을 부여하고, 카메라 UI를 앱에 통합할 수 있습니다.
-
-
-</p>
-
-<p>
- 하지만, 그러한 제어권이 필요하지 않은 경우라면 그저 {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} 인텐트를 사용해 이미지를 요청하면 됩니다.
-
- 이 인텐트를 시작하면 사용자에게 카메라 앱을 선택하라는 메시지가 표시되고(기본 카메라 앱이 이미 있는 경우) 그 앱이 사진을 촬영합니다.
-
- 이 카메라 앱은 촬영한 사진을 개발자의 앱의 {@link android.app.Activity#onActivityResult onActivityResult()} 메서드에 반환합니다.
-
-</p>
-
-<p>
- 이와 마찬가지로, 전화를 걸어야 하거나 사용자의 연락처에 액세스해야 하는 경우 등에는 적절한 인텐트를 만들거나 적절한 객체에 직접 액세스하도록 권한을 요청할 수 있습니다.
-
- 이 두 가지 방식에는 각각 장단점이 있습니다.
-
-</p>
-
-<p>
- 권한을 사용하는 경우:
-</p>
-
-<ul>
- <li>개발자가 직접 작업을 수행하는 경우 본인의 앱이 사용자 환경을 완전히 제어합니다.
- 다만, 그렇게 포괄적인 제어권을 가지면 적절한 UI를 디자인해야 하므로 작업이 복잡해집니다.
-
- </li>
-
- <li>사용자에게 권한을 부여하라는 메시지는 작업을 처음 수행할 때만 표시됩니다.
- 그 다음부터는 앱이 사용자로부터 더 이상의 상호작용을 요청하지 않아도 작업을 수행할 수 있습니다.
- 다만, 사용자가 해당 권한을 허용하지 않는 경우(또는 나중에 취소하는 경우), 앱은 해당 작업을 수행할 수 없게 됩니다.
-
-
- </li>
-</ul>
-
-<p>
- 인텐트를 사용하는 경우:
-</p>
-
-<ul>
- <li>작업을 위해 UI를 디자인하지 않아도 됩니다. 이는 인텐트를 처리하는 앱이 UI를 제공하기 때문입니다. 하지만, 이것은 즉 개발자에게 사용자 환경에 대한 제어권이 전혀 없다는 뜻이기도 합니다.
-
- 사용자는 어쩌면 개발자가 본 적도 없는 앱과 상호작용하고 있을지 모릅니다.
-
- </li>
-
- <li>사용자에게 해당 작업에 대한 기본 앱이 없는 경우, 시스템은 사용자에게 앱을 선택하라는 메시지를 표시합니다. 사용자가 기본 처리기를 지정하지 않으면 해당 작업을 수행할 때마다 추가 대화창을 거쳐야 할 수도 있습니다.
-
-
-
- </li>
-</ul>
-
-<h2 id="coding">런타임 권한에 대한 코딩</h2>
-
-<p>
- 새로운 M 개발자 미리 보기를 대상으로 앱을 개발하는 경우, 새 권한 모델을 사용해야 합니다.
- 이는 즉, 매니페스트에 필요한 권한을 선언하는 것 말고도 런타임에 자신이 해당 권한을 가지고 있는지도 확인해야 하며, 그러한 권한을 이미 가지고 있지 않으면 권한을 요청해야 한다는 뜻입니다.
-
-
-
-</p>
-
-<h3 id="enabling">
- 새 권한 모델 활성화하기
-</h3>
-
-<p>
- 새로운 M 개발자 미리 보기 권한 모델을 활성화하려면 앱의 <code>targetSdkVersion</code> 특성을 <code>"MNC"</code>로 설정하고, <code>compileSdkVersion</code>은 <code>"android-MNC"</code>로 설정하세요.
-
- 이렇게 하면 새 권한 기능이 모두 활성화됩니다.
-
-</p>
-
-<p>
- 미리 보기 릴리스에서는 <code>minSdkVersion</code>을 <code>"MNC"</code>로 설정해야만 미리 보기 SDK와 컴파일할 수 있습니다.
-
-</p>
-
-<h3 id="m-only-perm">
- M 미리 보기 전용 권한 지정하기
-</h3>
-
-<p>
- 새 <code>&lt;uses-permission-sdk-m&gt;</code> 요소를 앱 매니페스트에 사용하여 권한이 M 개발자 미리 보기에서만 필요하다는 것을 나타낼 수 있습니다.
- 권한을 이런 식으로 선언하면 앱이 이전 버전의 기기에 설치될 때마다 시스템에서 사용자에게 메시지를 표시하지도 않고 앱에 권한을 허용하지도 않습니다. <code>&lt;uses-permission-sdk-m&gt;</code> 요소를 사용하면 새 권한을 앱의 업데이트된 버전에 추가하면서도 사용자가 업데이트를 설치할 때 권한을 허용하라고 강제로 시키지 않아도 됩니다.
-
-
-
-
-
-
-</p>
-
-<p>
- 앱이 M 개발자 미리 보기를 갖춘 기기에서 실행되는 경우, <code>&lt;uses-permission-sdk-m&gt;</code>은 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>과 똑같이 동작합니다.
-
-
- 시스템은 사용자가 앱을 설치할 때 권한을 허용하라는 메시지를 표시하지 않고, 앱이 필요할 때마다 권한을 요청하게 됩니다.
-
-</p>
-
-<h3 id="prompting">
- 권한에 대한 메시지 표시하기
-</h3>
-
-<p>
- 앱이 새로운 M 개발자 미리 보기 권한 모델을 사용하는 경우, 앱이 M 미리 보기에서 실행되는 기기에서 처음 시작되었을 때 사용자에게 모든 권한을 허용하도록 요청하지 않습니다.
-
- 대신, 앱은 필요할 때마다 권한을 요청합니다.
- 앱이 권한을 요청하면 시스템이 사용자에게 대화창으로 표시합니다.
-
-</p>
-
-<p>
- 앱이 SDK 22 이하를 탑재한 기기에서 실행되는 경우, 앱은 기존 권한 모델을 사용합니다.
- 사용자가 앱을 설치하면 앱이 자신의 매니페스트에서 요청하는 모든 권한을 허용하라는 메시지가 표시되는데, 이때 <code>&lt;uses-permission-sdk-m&gt;</code>이라는 레이블이 붙은 권한은 예외입니다.
-
-
-</p>
-
-<h4 id="check-platform">앱이 실행되는 플랫폼 확인</h4>
-
-<p>
- 이 권한 모델은 M 개발자 미리 보기를 실행하는 기기에서만 지원됩니다.
- 이러한 메서드 중에서 호출하려면 앱은 우선 {@link android.os.Build.VERSION#CODENAME Build.VERSION.CODENAME} 값을 확인하여 자신이 어느 플랫폼에서 실행 중인지 확인해야 합니다.
-
-
- 기기가 M 개발자 미리 보기에서 실행 중인 경우, {@link android.os.Build.VERSION#CODENAME CODENAME}은 <code>"MNC"</code>입니다.
-
-</p>
-
-<h4 id="check-for-permission">앱에 필요한 권한이 있는지 확인</h4>
-
-<p>사용자가 권한을 필요로 하는 무언가를 하려고 시도하면, 앱은 자신이 현재 이 작업을 수행하는 데 필요한 권한을 가지고 있는지 확인합니다.
- 이렇게 하기 위해 앱은 <code>Context.checkSelfPermission( )</code>을 호출합니다.
-
-<i>permission_name</i> 사용자가 앱의 권한을 언제든 취소할 수 있기 때문에 앱은 사용자가 해당 권한을 이미 허용했다는 것을 알고 있더라도 확인 작업을 수행해야 합니다.
-
-
- 예를 들어, 사용자가 사진 촬영 앱을 사용하고자 한다면 앱은 <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>를 호출합니다.
-
-</p>
-
-<p class="table-caption" id="permission-groups">
- <strong>표 1.</strong> 권한과 권한 그룹.</p>
-<table>
- <tr>
- <th scope="col">권한 그룹</th>
- <th scope="col">권한</th>
- </tr>
-
- <tr>
- <td><code>android.permission-group.CALENDAR</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.READ_CALENDAR</code>
- </li>
- </ul>
- <ul>
- <li>
- <code>android.permission.WRITE_CALENDAR</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.CAMERA</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.CAMERA</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.CONTACTS</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.READ_CONTACTS</code>
- </li>
- <li>
- <code>android.permission.WRITE_CONTACTS</code>
- </li>
- <li>
- <code>android.permission.READ_PROFILE</code>
- </li>
- <li>
- <code>android.permission.WRITE_PROFILE</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.LOCATION</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.ACCESS_FINE_LOCATION</code>
- </li>
- <li>
- <code>android.permission.ACCESS_COARSE_LOCATION</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.MICROPHONE</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.RECORD_AUDIO</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.PHONE</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.READ_PHONE_STATE</code>
- </li>
- <li>
- <code>android.permission.CALL_PHONE</code>
- </li>
- <li>
- <code>android.permission.READ_CALL_LOG</code>
- </li>
- <li>
- <code>android.permission.WRITE_CALL_LOG</code>
- </li>
- <li>
- <code>com.android.voicemail.permission.ADD_VOICEMAIL</code>
- </li>
- <li>
- <code>android.permission.USE_SIP</code>
- </li>
- <li>
- <code>android.permission.PROCESS_OUTGOING_CALLS</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.SENSORS</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.BODY_SENSORS</code>
- </li>
- </ul>
- <ul>
- <li>
- <code>android.permission.USE_FINGERPRINT</code>
- </li>
- </ul>
- </td>
- </tr>
-
- <tr>
- <td><code>android.permission-group.SMS</code></td>
- <td>
- <ul>
- <li>
- <code>android.permission.SEND_SMS</code>
- </li>
- <li>
- <code>android.permission.RECEIVE_SMS</code>
- </li>
- <li>
- <code>android.permission.READ_SMS</code>
- </li>
- <li>
- <code>android.permission.RECEIVE_WAP_PUSH</code>
- </li>
- <li>
- <code>android.permission.RECEIVE_MMS</code>
- </li>
- <li>
- <code>android.permission.READ_CELL_BROADCASTS</code>
- </li>
- </ul>
- </td>
- </tr>
-
-</table>
-
-<h4 id="request-permissions">필요한 경우 권한 요청</h4>
-
-<p>앱이 자신에게 필요한 권한을 이미 가지고 있지 않은 경우, 앱은 <code>Activity.requestPermissions(String[], int)</code> 메서드를 호출하여 적절한 권한(여러 개일 수 있음)을 요청합니다.
-
- 앱은 원하는 권한을 요청하면서 정수 "요청 코드"를 요청합니다.
-
- 이 메서드는 비동기화 방식으로 기능합니다. 이는 즉각적으로 반환되며, 사용자가 대화 상자에 응답한 다음에는 시스템이 결과를 가지고 앱의 콜백 메서드를 호출하여 앱이 <code>requestPermissions()</code>에 전달한 "요청 코드"와 같은 코드를 전달합니다.
-
-
-</p>
-
- <p>다음 코드는 앱에 사용자의 연락처를 읽을 권한이 있는지 코드 확인을 하고, 필요한 경우 해당 권한을 요청합니다.
-</p>
-
-<pre>
-if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
- != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
- MY_PERMISSIONS_REQUEST_READ_CONTACTS);
-
- // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
- // app-defined int constant
-
- return;
-}
-</pre>
-
-<h4 id="handle-response">권한 요청 응답 처리하기</h4>
-
-<p>
- 앱이 권한을 요청하면 시스템이 사용자에게 대화 상자를 표시합니다.
- 사용자가 응답하면 시스템은 앱의 <code>Activity.onRequestPermissionsResult(int, String[], int[])</code>를 불러내 이를 사용자 응답에 전달합니다.
-
- 앱은 해당 메서드를 재정의해야 합니다. 이 콜백에는 개발자가 <code>requestPermissions()</code>에 전달한 것과 같은 요청 코드가 전달됩니다.
-
- 예를 들어 어느 앱이 <code>READ_CONTACTS</code> 액세스를 요청한다면 다음과 같은 콜백 메서드를 가지고 있을 수 있습니다.
-
-
-</p>
-
-<pre>
-&#64;Override
-public void onRequestPermissionsResult(int requestCode,
- String permissions[], int[] grantResults) {
- switch (requestCode) {
- case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
- if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-
- // permission was granted, yay! do the
- // calendar task you need to do.
-
- } else {
-
- // permission denied, boo! Disable the
- // functionality that depends on this permission.
- }
- return;
- }
-
- // other 'switch' lines to check for other
- // permissions this app might request
- }
-}
-</pre>
-
- <p>사용자가 권한을 허용하면 시스템은 앱 매니페스트에 그 기능 영역에 대해 목록으로 표시된 모든 권한을 해당 앱에 부여합니다.
- 사용자가 요청을 거부하면 적절한 조치를 취해야 합니다.
- 예를 들어 이 권한에 좌우되는 메뉴 작업을 모두 비활성화할 수 있습니다.
-
- </li>
-</p>
-
-<p>
- 시스템이 사용자에게 권한을 허용하도록 요청하면 사용자에게는 시스템에 해당 권한을 다시 요청하지 말라고 지시할 선택권이 있습니다.
- 그런 경우, 앱이 해당 권한을 요청하기 위해 <code>requestPermissions()</code>를 사용하면 시스템이 즉시 요청을 거부합니다.
-
- 이 경우 시스템은 사용자가 명시적으로 개발자의 요청을 다시 거부한 것처럼 <code>onRequestPermissionsResult()</code>를 호출합니다.
-
- 이러한 이유로, 앱은 사용자와의 직접적인 상호작용이 일어났다고 가정해서는 안 됩니다.
-
-</p>
-
-<h2 id="testing">런타임 권한 테스트</h2>
-
-
-<p>
- M 개발자 미리 보기를 대상으로 삼고 앱을 개발하는 경우, 이 앱이 권한을 적절하게 처리하는지 테스트해보아야 합니다.
- 앱이 실행될 때 특정 권한을 가지고 있다고 가정해서는 안 됩니다.
- 앱을 처음 시작할 때에는 아무런 권한도 없을 가능성이 높고, 사용자가 언제든 권한을 취소하거나 복원할 수 있기 때문입니다.
-
-
-</p>
-
-<p>
- 앱을 테스트하여 모든 권한 관련 상황에서 제대로 작동하는지 확인하는 것이 좋습니다.
- M 미리 보기 SDK에서는 새로운 <a href="{@docRoot}tools/help/adb.html">Android 디버그 브리지(adb)</a> 명령을 제공하여 여러분이 시도해 보아야 하는 권한 설정이 무엇이든 앱을 테스트할 수 있도록 하였습니다.
-
-
-
-</p>
-
-<h3>
- 새로운 adb 명령 및 선택 사항
-</h3>
-
-<p>
- M 미리 보기 SDK 플랫폼 도구에서는 여러 가지 새로운 명령을 제공하여 앱이 권한을 처리하는 방식을 테스트해볼 수 있습니다.
-
-</p>
-
-<h4>
- 권한으로 설치
-</h4>
-
-<p>
- <a href="{@docRoot}tools/help/adb.html#move"><code>adb
- install</code></a> 명령의 새로운 <code>-g</code> 선택 항목을 사용하면 앱을 설치하고 해당 앱의 매니페스트에 목록으로 표시된 모든 권한을 허용합니다.
-
-</p>
-
-<pre class="no-pretty-print">
-$ adb install -g &lt;path_to_apk&gt;
-</pre>
-
-<h4>
- 권한 허용 및 취소
-</h4>
-
-<p>
- 새로운 ADB <a href="{@docRoot}tools/help/adb.html#pm">패키지 관리자(pm)</a> 명령을 사용하면 설치된 앱에 권한을 허용하고 취소할 수 있습니다. 이 기능은 자동화 설정에서 유용하게 쓰일 수 있습니다.
-
-
-</p>
-
-<p>
- 권한을 허용하려면, 패키지 관리자의 <code>grant</code> 명령을 사용하세요.
-</p>
-
-<pre class="no-pretty-print">
-$ adb pm grant &lt;package_name&gt; &lt;permission_name&gt;
-</pre>
-
-<p>
- 예를 들어 com.example.myapp 패키지 권한을 허용하여 오디오를 녹음하려면 이 명령을 사용하면 됩니다.
-
-</p>
-
-<pre class="no-pretty-print">
-$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO
-</pre>
-
-<p>
- 권한을 취소하려면, 패키지 관리자의 <code>revoke</code> 명령을 사용하세요.
-</p>
-
-<pre class="no-pretty-print">
-$ adb pm revoke &lt;package_name&gt; &lt;permission_name&gt;
-</pre>
-
-<h2 id="best-practices">모범 사례</h2>
-
-<p>
- 새 권한 모델을 사용하면 사용자에게 보다 원활한 환경을 제공하고, 앱을 더욱 쉽게 설치하며 앱이 어떤 작업을 하고 있는지 바로 확인할 수 있습니다.
-
- 새 모델의 장점을 최대한 활용할 수 있도록 다음과 같은 모범 사례를 추천해 드립니다.
-
-</p>
-
-
-<h3 id="bp-what-you-need">필요한 권한만 요청</h3>
-
-<p>
- 권한을 요청할 때마다 사용자에게는 결정을 내리라는 강요를 하는 셈입니다.
- 사용자가 요청을 거절하면 앱의 기능이 저하됩니다.
- 때문에 이러한 요청을 하는 횟수를 최소한으로 줄이는 것이 좋습니다.
-</p>
-
-<p>
- 예를 들어 앱이 권한을 요청하는 대신 <a href="{@docRoot}guide/components/intents-filters.html">인텐트</a>를 사용해 필요한 기능을 얻을 수 있는 경우도 꽤 많습니다.
-
- 앱이 전화기의 카메라를 사용해 사진을 촬영해야 하는 경우, 앱은 {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} 인텐트를 사용할 수 있습니다.
-
-
- 앱이 인텐트를 실행하면 시스템이 사용자에게 메시지를 표시해 이미 설치된 카메라 앱을 선택하여 사진을 촬영하도록 합니다.
-
-
-</p>
-
-<h3 id="bp-dont-overwhelm">
- 사용자에게 부담을 주지 말 것
-</h3>
-
-<p>
- 사용자에게 엄청나게 많은 수의 권한 요청을 한꺼번에 들이밀면 사용자가 부담을 느끼고 앱을 종료해버리는 결과를 초래할 수 있습니다. 대신 권한이 필요할 때마다 요청하는 것이 좋습니다.
-
-
-</p>
-
-<p>
- 일부 경우에는 앱에 절대적으로 꼭 필요한 권한이 한 개 이상 있을 수도 있습니다. 그런 경우에는 앱이 시작되자마자 해당 권한을 모두 요청하는 것을 권장합니다.
-
- 예를 들어 사진 앱을 만들면 앱이 기기 카메라로 액세스할 수 있는 권한이 필요합니다.
- 사용자가 앱을 처음으로 시작할 때 카메라를 사용할 권한을 요청받아도 놀라지는 않을 것입니다.
-
- 하지만 같은 앱에 사용자의 연락처과 사진을 공유하는 기능도 있다고 가정한다면 이 경우 해당 권한을 첫 시작 시점에 요청하는 것은 별로 권장할 만한 일이 <em>아닙니다.</em>
-
- 대신, 사용자가 "공유" 기능을 요청하려 할 때까지 기다렸다가 그 때 해당 권한을 요청하면 됩니다.
-
-</p>
-
-<p>
- 앱이 튜토리얼을 제공하는 경우, 튜토리얼 시퀀스가 다 끝날 무렵에 앱의 필수 권한을 요청하는 것이 이치에 맞을 수 있습니다.
-
-</p>
-
-<h3 id="bp-explain">
- 권한이 필요한 이유 설명
-</h3>
-
-<p>
- 개발자가 <code>requestPermissions()</code>를 호출하면 시스템이 표시하는 권한 대화창에는 앱이 원하는 권한이 무엇인지는 나타나 있지만 그것이 필요한 이유는 설명하지 않습니다.
-
- 사용자가 이런 것을 의아하게 여기는 경우가 있을 수 있습니다.
- 우선 사용자에게 앱이 왜 그런 권한을 원하는지 설명한 다음 <code>requestPermissions()</code>를 호출하는 것이 좋습니다.
-
-</p>
-
-<p>
- 예를 들어 사진 앱인 경우 위치 서비스를 이용하고자 할 수 있습니다. 그래야 사진에 지오태그를 표시할 수 있기 때문입니다.
- 일반적인 사용자는 사진에 위치 정보를 담을 수 있다는 점을 모를 수도 있고, 그러면 사진 앱이 왜 위치를 알고 싶어 하는지 의아하게 여길 수 있습니다.
-
- 그러므로 이런 경우에는 앱이 사용자에게 이런 기능에 대해 <em>미리</em> 알려드린 후 <code>requestPermissions()</code>를 호출하는 것이 좋습니다.
-
-
-</p>
-
-<p>
- 이를 수행하기 위한 한 가지 방법은 이러한 요청을 앱 튜토리얼에 넣는 것입니다. 튜토리얼에는 앱의 각 기능을 표시할 수 있고, 그러면서 어느 권한이 필요한지 설명할 수도 있기 때문입니다.
-
- 예를 들어 사진 앱의 튜토리얼에서 "연락처 목록의 지인들과 사진 공유" 기능을 시연한 다음 사용자에게 앱이 사용자의 연락처를 보려면 권한을 부여해야 한다고 알리면 됩니다.
-
-
- 그런 다음, 앱이 <code>requestPermissions()</code>를 호출하여 사용자에게 해당 액세스를 요청합니다.
- 물론 튜토리얼을 따르지 않는 사용자도 있게 마련이므로 앱의 정상 작동 중에 권한을 확인하고 요청해야 합니다.
-
-
-</p>
diff --git a/docs/html-intl/intl/ko/preview/index.jd b/docs/html-intl/intl/ko/preview/index.jd
deleted file mode 100644
index badb9f6095aa..000000000000
--- a/docs/html-intl/intl/ko/preview/index.jd
+++ /dev/null
@@ -1,70 +0,0 @@
-page.title=Android M 개발자 미리 보기
-page.tags="preview",
-meta.tags="preview, M preview", androidm
-fullpage=true
-section.landing=true
-header.hide=1
-footer.hide=1
-@jd:body
-
-<section class="dac-expand dac-hero dac-light" >
- <div class="wrap">
- <div class="cols dac-hero-content">
- <div class="col-9of16 col-push-7of16 dac-hero-figure">
- <img class="dac-hero-image" src="{@docRoot}images/home/devices-hero_620px_2x.png" srcset="{@docRoot}images/home/devices-hero_620px.png 1x,
- {@docRoot}images/home/devices-hero_620px_2x.png 2x">
- </div>
- <div class="col-7of16 col-pull-9of16">
- <h1 class="dac-hero-title">Android M 개발자 미리 보기</h1>
- <p class="dac-hero-description">
- Android의 다음 버전을 만나볼 준비가 되셨습니까? 여러분의 앱을 Nexus 5, 6, 9 및 Player에서 테스트해보십시오.
- 새로운 내용은 무엇인지 둘러보십시오. <strong>런타임 권한</strong>, <strong>Doze</strong> 및 <strong>앱 대기 모드</strong> 절전 기능, 새로 나온 <strong>지원 기술</strong>, 이외에도 많은 것이 있습니다.
-
-
- </p>
-
- <a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
- <span class="dac-sprite dac-auto-chevron"></span>
- 지금 시작하세요!
-</a><br>
- <a class="dac-hero-cta" href="{@docRoot}preview/support.html">
- <span class="dac-sprite dac-auto-chevron"></span>
- Developer Preview 3 (final SDK)</a>
- </div>
- </div>
- <div class="dac-section dac-small">
- <div class="resource-widget resource-flow-layout col-16"
- data-query="collection:preview/landing/resources"
- data-cardSizes="6x2"
- data-maxResults="6"></div>
- </div>
- </div>
-</section>
-
-<section class="dac-section dac-gray"><div class="wrap">
- <h1 class="dac-section-title">리소스</h1>
- <div class="dac-section-subtitle">
- 앱을 Android M에 대비시키는 데 유용한 중요 정보입니다.
- </div>
-
- <div class="resource-widget resource-flow-layout col-16"
- data-query="collection:preview/landing/more"
- data-cardSizes="6x6"
- data-maxResults="16"></div>
-
- <ul class="dac-section-links">
- <li class="dac-section-link">
- <a href="https://code.google.com/p/android-developer-preview/">
- <span class="dac-sprite dac-auto-chevron"></span>
- 문제 보고
-</a>
- </li>
- <li class="dac-section-link"><a href="http://g.co/dev/AndroidMDevPreview">
- <span class="dac-sprite dac-auto-chevron"></span>
- G+ 커뮤니티 가입
-</a>
- </li>
- </ul>
- </div>
-</section>
-
diff --git a/docs/html-intl/intl/ko/preview/license.jd b/docs/html-intl/intl/ko/preview/license.jd
deleted file mode 100644
index 71c9d45fff4c..000000000000
--- a/docs/html-intl/intl/ko/preview/license.jd
+++ /dev/null
@@ -1,143 +0,0 @@
-page.title=라이선스 계약
-
-@jd:body
-
-<p>
-Android SDK 미리보기를 시작하려면 우선 다음과 같은 사용 약관에 동의해야 합니다. 아래에 설명한 바와 같이, 이것은 Android SDK의 미리 보기 버전이며 변경될 가능성이 있고 이를 사용하는 위험 부담은 계약자 본인에게 있음을 유의하십시오.
- Android SDK 미리보기는 안정된 릴리스가 아니며, 오류나 결함이 들어있을 수 있고 이 때문에 컴퓨터 시스템, 기기 및 데이터에 심각한 손상을 초래할 수 있습니다.
-</p>
-
-<p>
-이것은 Android SDK 미리 보기 라이선스 계약서입니다(이하 "라이선스 계약").
-</p>
-<div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px">
-1. 개요
-
-1.1 Android SDK 미리 보기(본 라이선스 계약에서는 "미리 보기"라고 칭하며, 구체적으로 Android 시스템 파일, 패키지 API 및 미리 보기 라이브러리 파일이 이용 가능한 경우 및 이용 가능하게 전환된 경우 이를 포함한 것을 가리킴)는 본 라이선스 계약 조건에 따라 계약자에게 사용을 허여합니다. 본 라이선스 계약은 미리 보기 사용과 관련하여 계약자와 Google 간에 법적 구속력이 있는 계약을 체결합니다.
-
-1.2 "Android"는 기기를 위한 Android 소프트웨어 스택을 의미합니다. 이는 http://source.android.com/ URL에 위치하며 수시로 업데이트되는 Android 오픈 소스 프로젝트에서 제공됩니다.
-
-1.3 "Google"은 미국 1600 Amphitheatre Parkway, Mountain View, CA 94043에 본사를 두고 있는 델라웨어주 법인인 Google Inc.를 의미합니다.
-
-2. 라이선스 계약에 동의
-
-2.1 이 미리 보기를 사용하려면, 먼저 라이선스 계약에 동의해야 합니다. 이 라이선스 계약에 동의하지 않고 미리 보기를 사용해서는 안 됩니다.
-
-2.2 수락을 클릭하고/거나 미리 보기를 사용하면 본 라이선스 계약 조건에 동의하는 것으로 간주됩니다.
-
-2.3 미국법 또는 현재 거주 중이거나 미리 보기를 사용하는 국가를 포함하여 다른 국가의 법에 따라 미리 보기를 받는 것이 금지된 경우, 미리 보기를 사용할 수 없으며 본 라이선스 계약을 수락할 수 없습니다.
-
-2.4 회사 또는 단체 내에서 내부적으로 미리 보기를 사용하며 고용주 또는 기타 단체를 대신하여 본 라이선스 계약 준수에 동의하는 경우, 계약자의 고용주나 그 단체에 본 라이선스 계약에 대한 구속력을 부여할 수 있는 모든 법적 권한을 계약자가 갖고 있음을 진술하고 보증합니다. 구속력을 부여할 수 있는 법적 권한이 없을 경우, 고용주 또는 기타 단체를 대신하여 본 라이선스 계약에 동의하거나 미리 보기를 사용할 수 없습니다.
-
-3. Google이 허하는 미리 보기 라이선스
-
-3.1 본 라이선스 계약의 조건에 따라 Google은 계약자에게 로열티 없고 양도 불가능하며 비독점적이고 2차 인가를 불허하며, 한정되고 무효화할 수 있는 미리 보기 사용 권한을 허용하여 회사 또는 조직 내에서 개인적 또는 내부적으로 사용할 수 있도록 합니다. 이는 Android 플랫폼에서 실행되는 애플리케이션을 개발할 목적으로만 사용해야 합니다.
-
-3.2 계약자는 SDK에 존재하는 지적 재산권을 포함한 SDK에 대한 모든 법적인 권리, 소유권 및 이익이 Google 또는 제3자에게 있음에 동의합니다 "지적 재산권"은 모든 특허법, 저작권법, 영업비밀법, 상표법상 존재하는 모든 권리 및 기타 모든 재산권을 의미합니다. Google은 계약자에게 명시적으로 부여하지 않은 모든 권리를 보유합니다.
-
-3.3 본 라이선스 계약에 명시적으로 허용된 용도 외에는 미리 보기를 사용할 수 없습니다. 해당 제3자 라이선스 요건이 허용하는 범위를 제외하고 계약자는 미리 보기의 일부분을 (a) 복사(백업 목적 제외), 수정, 개작, 재배포, 역컴파일, 리버스 엔지니어링, 분해하거나 이를 통해 파생물을 생성하거나 (b) 개인 컴퓨터를 제외한 모바일 단말기 또는 기타 모든 하드웨어 기기에 미리 보기의 일부를 로드하거나, 미리 보기의 일부를 다른 소프트웨어와 결합하거나 미리 보기의 일부가 통합된 일체의 소프트웨어나 기기를 배포해서는 안 됩니다.
-
-3.4 계약자는 미리 보기에서 파생된 소프트웨어 개발 키트의 배포, 이러한 키트 생성에 참여 또는 홍보를 포함하되 이에 국한되지 않고, Android의 단편화를 야기하는 어떠한 행동도 취하지 않을 것임에 동의합니다.
-
-3.5 오픈 소스 소프트웨어 라이선스에 의거한 미리 보기 구성요소의 사용, 재생산, 배포에는 본 라이선스 계약이 아닌, 해당 오픈 소스 소프트웨어 라이선스의 조건이 적용됩니다. 계약자는 허용된 모든 권한 하에서 그러한 오픈 소스 소프트웨어 라이선스에 관해 충실한 피허가자로서의 자세를 견지할 것이며 그러한 권한을 종료, 일시 중단 또는 침해하는 행위를 삼갈 것을 동의합니다.
-
-3.6 계약자는 Google이 제공하는 SDK의 형태 및 특성이 사전 통지 없이 변경될 수 있음에 동의하며, 이전 버전의 미리 보기에서 개발된 애플리케이션이 이후 버전의 SDK와 호환되지 않을 수 있음에 동의합니다. 계약자는 계약자 또는 사용자에게 사전 통지 없이 SDK(또는 SDK에 포함된 기능) 제공을(영구적 또는 일시적으로) 중단할 수 있는 권한이 Google에게 있음에 동의합니다.
-
-3.7 본 라이선스 계약은 계약자에게 Google의 상표명, 상표, 서비스 표시, 로고, 도메인 이름, 기타 독특한 브랜드 특징에 대한 사용 권한을 부여하지 않습니다.
-
-3.8 계약자는 SDK에 부착되어 있거나 포함되어 있는 모든 소유권 고지 사항(저작권 및 상표 고지 사항 포함)을 제거, 변경 또는 불분명하게 만들지 않을 것에 동의합니다.
-
-4. 계약자의 미리 보기 사용
-
-4.1 Google은 본 라이선스 계약의 어떤 조항도 계약자(또는 계약자의 사용 허가자)가 미리 보기를 사용하여 개발한 소프트웨어 애플리케이션에 대한 권리, 소유권 또는 이익, 그리고 해당 애플리케이션에 존재하는 모든 지적 재산권을 부여하지 않는다는 점에 동의합니다.
-
-4.2 계약자는 (a) 본 라이선스 계약 그리고 (b) 모든 준거법, 규정 또는 관련 관할권 내에서 일반적으로 수용되는 관행 또는 지침(미국 또는 기타 관련 국가로/에서의 데이터 또는 소프트웨어 수출과 관련된 모든 법률 포함)에서 허용하는 용도에 한하여 미리 보기를 사용하고 애플리케이션을 작성하는 것에 동의합니다.
-
-4.3 계약자는 일반 대중 사용자를 대상으로 미리 보기를 사용하여 애플리케이션을 개발하는 경우, 해당 사용자의 프라이버시 및 법적 권리를 보호하는 것에 동의합니다. 사용자가 계약자에게 사용자 이름, 비밀번호 또는 기타 로그인 정보나 개인 정보를 제공하는 경우, 계약자는 제공된 정보가 자신의 애플리케이션에 제공된다는 사실을 사용자에게 알려야 하며, 반드시 법적으로 적절한 개인정보 보호정책 고지 및 보호를 해당 사용자에게 제공해야 합니다. 애플리케이션에서 사용자가 제공한 개인정보나 민감한 정보를 저장하는 경우, 이를 안전하게 처리해야 합니다. 사용자들이 애플리케이션에 Google 계정 정보를 제공하는 경우, 애플리케이션은 해당 사용자의 Google 계정에 액세스하는 목적으로만, 그리고 각 사용자가 허용한 범위 내의 한정된 목적으로만 이러한 정보를 사용해야 합니다.
-
-4.4 계약자는 Google 또는 기타 모든 타사의 서버, 네트워크 또는 기타 모든 재산 또는 서비스를 허가 없이 방해, 교란, 손상 또는 액세스하는 애플리케이션의 개발 또는 배포를 포함한 하등의 행위에 미리 보기를 이용하지 않을 것임을 동의합니다.
-
-4.5 계약자는 자신이 Android 및/또는 Android용 애플리케이션을 통해 생성, 전송 또는 표시하는 모든 데이터, 콘텐츠 또는 리소스 그리고 그로 인한 결과(Google이 입을 수 있는 모든 피해나 손실 포함)에 대해 전적으로 책임이 있다는 것(그리고 Google은 계약자 또는 모든 제3자에 대한 책임이 없다는 것)에 동의합니다.
-
-4.6 계약자는 본 라이선스 계약, 모든 해당 제3자 계약 또는 서비스 약관, 또는 모든 준거법 또는 규정에 의거한 계약자 의무 위반, 그리고 그로 인한 결과(Google 또는 제3자가 입을 수 있는 모든 피해나 손실 포함)에 전적으로 책임이 있다는 것(그리고 Google은 계약자 또는 모든 제3자에 대한 책임이 없다는 것)에 동의합니다.
-
-4.7 이 미리 보기는 현재 개발 단계에 있으며, 계약자의 테스트와 피드백은 그러한 개발 과정에 중요한 부분을 차지합니다. 미리 보기를 사용함으로써 계약자는 일부 기능의 구현은 아직 개발 중인 상태이며 미리 보기가 안정된 릴리스처럼 완벽하게 기능할 것이라 믿고 사용해서는 안 된다는 점을 인지하는 것으로 간주합니다. 계약자는 이 미리 보기를 사용한 애플리케이션을 공개적으로 배포 또는 배송하지 않기로 동의합니다. 이 미리 보기는 공식 Android SDK가 출시된 이후에는 더 이상 지원되지 않기 때문입니다.
-
-5. 계약자의 개발자 자격 증명
-
-5.1 계약자는 Google이 발급했거나 자신이 선택한 모든 개발자 자격 증명에 대한 기밀성을 유지할 책임이 있으며 계약자의 개발자 자격 증명 하에 개발된 모든 애플리케이션에 대한 전적인 책임이 있음에 동의합니다.
-
-6. 개인정보 보호정책 및 정보
-
-6.1 미리 보기를 지속적으로 혁신하고 개선하기 위해, Google은 고유 식별자, 관련 IP 주소, 소프트웨어 버전 번호, 미리 보기에서 사용 중인 도구 및/또는 서비스와 도구의 사용법에 대한 정보를 포함하되 이에 국한되지 않고 소프트웨어에서 특정 사용량 통계 정보를 수집할 수 있습니다. 그러한 정보를 수집하기 전에 미리 보기는 계약자에게 이를 통지하고 동의를 구할 것입니다. 계약자가 동의하지 않을 경우 정보를 수집하지 않습니다.
-
-6.2 수집된 데이터는 모두 취합된 형태로 미리 보기 개선을 위해 검토되며, Google의 개인정보 보호정책에 따라 유지 관리됩니다. 이 정보는 http://www.google.com/policies/privacy/를 참조하십시오.
-
-7. 제3자 애플리케이션
-
-7.1 제3자가 개발한 애플리케이션을 실행하거나 제3자가 제공한 데이터, 콘텐츠 또는 리소스에 액세스하기 위해 미리 보기를 사용하는 경우, 계약자는 Google이 그러한 애플리케이션, 데이터, 콘텐츠 또는 리소스에 대한 책임이 없음에 동의합니다. 계약자는 그러한 제3자 애플리케이션을 통해 자신이 액세스한 모든 데이터, 콘텐츠 또는 리소스에 대한 책임은 그것을 만든 사람에게 있음에 동의합니다. 또한 계약자가 그러한 모든 제3자 애플리케이션, 데이터, 콘텐츠 또는 리소스를 사용하거나 액세스함으로써 비롯된 모든 피해나 손실에 대한 책임이 Google에게 없음에 동의합니다.
-
-7.2 그러한 제3자 애플리케이션을 통해 계약자에게 제공된 데이터, 콘텐츠 그리고 리소스는 그것을 제공한 제공자(또는 제공자를 대신하는 기타 개인 또는 기업)가 소유한 지적 재산권에 의해 보호될 수 있음을 유의해야 합니다. 그러한 데이터, 콘텐츠 또는 리소스(전부 또는 일부)를 수정, 임대, 리스, 대여, 판매, 배포하거나 이를 기반으로 파생물을 생성해서는 안 됩니다. 단, 관련 소유자로부터 그러한 작업을 수행해도 좋다는 허락을 받은 경우에는 예외입니다.
-
-7.3 계약자는 그러한 제3자 애플리케이션, 데이터, 콘텐츠 또는 리소스의 사용은 계약자와 관련 제3자 간에 체결하는 별도의 계약 조건의 적용을 받는다는 것을 인정합니다.
-
-8. Google API 사용
-
-8.1 Google Data API
-
-8.1.1 Google에서 데이터를 검색하기 위해 API를 사용하는 경우, 그러한 데이터가 Google 또는 데이터를 제공하는 당사자(또는 당사자를 대신하는 기타 개인 또는 기업)가 소유한 지적 재산권에 의해 보호될 수 있음을 인정합니다. 그러한 API를 사용하는 경우, 추가적인 서비스 약관의 적용을 받을 수 있습니다. 관련 서비스 약관에 허용되지 않은 한, 그러한 데이터(전부 또는 일부)를 변경, 임대, 리스, 대여, 판매, 배포하거나 이를 기반으로 파생물을 생성해서는 안 됩니다.
-
-8.1.2 Google에서 사용자 데이터를 검색하기 위해 API를 사용하는 경우, 계약자는 사용자로부터 명시적인 동의를 얻은 경우에 한하여, 그리고 해당 사용자가 허용한 범위 내의 한정된 목적으로만 데이터를 검색해야 합니다.
-
-9. 라이선스 계약 종료
-
-9.1 본 라이선스 계약은 계약자 또는 Google에 의해 아래와 같은 조건 하에 종료될 때까지 계속 적용됩니다.
-
-9.2 계약자가 라이선스 계약을 종료하고자 하는 경우, 미리 보기 및 관련 개발자 자격 증명 일체의 사용을 중단하는 것으로 그러한 의사를 피력할 수 있습니다.
-
-9.3 Google은 언제든 이유 여하를 불문하고 계약자에게 통고하여 라이선스 계약을 종료할 수 있습니다.
-
-9.4 본 라이선스 계약은 통보 또는 여타의 행위 없이도 자동으로 종료됩니다. 이에 해당되려면 다음과 같은 조건이 수반되어야 합니다.
-(A) Google이 계약자가 거주하는 국가 또는 계약자가 서비스를 사용하는 지역에서 미리 보기 또는 미리 보기의 특정 부분 제공을 중지하는 경우 및
-(B) Google이 Android SDK의 최종 릴리스 버전을 발행하는 경우.
-
-9.5 본 라이선스 계약이 종료되면 라이선스 계약으로 계약자에게 허용한 라이선스가 취소되며, 이에 따라 계약자는 미리 보기 사용을 즉시 모두 중단해야 하고 제 10, 11, 12 및 14절의 조항이 기한 없이 유지됩니다.
-
-10. 면책 조항
-
-10.1 계약자는 미리 보기 이용에 대한 위험 부담이 전적으로 본인에게 있으며, Google이 일체의 보증 없이 미리 보기를 "있는 그대로" 그리고 "이용 가능한" 상태로 제공한다는 것을 분명히 이해하고 동의합니다.
-
-10.2 미리 보기 이용 및 이용 과정에서 다운로드하거나 얻게 되는 모든 자료를 사용하는 것은 본인의 재량에 따르며 이에 대한 위험 부담이 전적으로 본인에게 있으며, 그러한 사용으로 인해 발생하는 컴퓨터 시스템 또는 다른 기기의 손상 또는 데이터 손실에 대한 책임은 전적으로 본인에게 있습니다. 전술한 조항을 제한하지 않는 범위 내에서 계약자는 미리 보기가 안정된 릴리스가 아니며 오류, 결함 및 보안 취약성이 포함되어 있을 수 있어 그 결과로 중대한 손상을 유발할 수 있다는 점을 이해하는 것으로 간주합니다. 여기에는 계약자의 컴퓨터 시스템 또는 기타 기기의 완전하고 돌이킬 수 없는 손실도 포함됩니다.
-
-10.3 더 나아가, Google은 상품성, 특정 목적에 대한 적합성 및 비침해의 묵시적 보증 등을 포함하되 이에 국한되지 않고 명시적이든 묵시적이든 모든 종류의 보증 및 조건을 명시적으로 부인합니다.
-
-11. 책임 한계
-
-11.1 계약자는 계약자에게 발생할 수 있는 직접, 간접, 부수적, 특별, 결과적 또는 징벌적 손해에 대해 그 어떤 책임 이론에 근거해서도 Google, 해당 자회사, 계열사 및 사용 허가자가 어떠한 책임도 지지 아니함을 분명히 이해하고 동의합니다. 이러한 손해에는 Google 또는 해당 대리자가 이러한 손실 발생 가능성에 대해 통지를 받았거나 이러한 사항을 인식했는지에 상관없이 모든 데이터 손실이 포함됩니다.
-
-12. 면책
-
-12.1 법률에 의해 허용되는 최대한의 범위 안에서 계약자는 (a) 미리 보기 사용, (b) 계약자가 미리 보기에서 개발한 일체의 애플리케이션에서 초래된 모든 사람의 저작권, 상표, 영업비밀, 트레이드 드레스, 특허 또는 기타 지적 재산권의 침해, 또는 어떤 사람의 명예를 훼손하거나 초상권 또는 개인정보 보호정책을 침해함 또는 (C)계약자 본인이 본 라이선스 계약을 위반함으로써 발생하거나 생기는 모든 청구, 조치, 소송 또는 절차, 그리고 모든 손실, 책임, 손해, 경비(합리적인 변호사 비용 포함)로부터 Google을 옹호하고, 면책시키고, Google이 손해를 입지 않도록 하는 데 동의합니다.
-
-13. 라이선스 계약 변경
-
-13.1 미리 보기의 새로운 버전을 배포할 때, Google은 본 라이선스 계약의 내용을 변경할 수 있습니다. 그러한 변경이 이뤄진 경우, Google은 미리 보기가 제공되는 웹사이트에 새로운 라이선스 계약 버전을 게재할 것입니다.
-
-14. 일반 법적 조건
-
-14.1 본 라이선스 계약은 계약자와 Google 간의 모든 법적 계약을 구성하며, 계약자의 미리 보기 사용을 규제하고(별도의 서면 계약을 통해 Google이 계약자에게 제공하는 모든 서비스는 제외), 미리 보기와 관련하여 이전에 계약자와 Google이 맺은 모든 계약을 완전히 대체합니다.
-
-14.2 계약자는 Google이 라이선스 계약에 포함된(또는 관련 법률에 의해 Google이 향유하는) 법적 권리 또는 구제수단을 행사하거나 집행하지 않더라도, Google이 권리를 공식적으로 포기한 것으로 간주하지 않으며, Google이 계속해서 그러한 권리 또는 구제수단을 이용할 수 있음에 동의합니다.
-
-14.3 본 라이선스 계약의 조항이 무효라고 이 사안에 관한 판결을 할 수 있는 관할권을 가진 법원이 판결할 경우, 그 조항은 라이선스 계약의 나머지 조항에 영향을 미치지 않는 형태로 라이선스 계약에서 제거됩니다. 본 라이선스 계약의 나머지 조항은 여전히 유효하며 집행 가능합니다.
-
-14.4 계약자는 Google이 모회사가 되는 회사 그룹에 속한 각 회사가 본 라이선스 계약의 제3수익자이며, 그러한 다른 회사들이 그들에게 이익(또는 유리한 권리)을 부여하는 본 라이선스 계약의 모든 조항을 직접 행사하고 적용할 수 있는 권리를 가진다는 데 동의합니다. 그 외에는 다른 어떤 개인이나 회사도 본 라이선스 계약의 제3수익자가 될 수 없습니다.
-
-14.5 수출 규제. 미리 보기는 미국의 수출법과 규정의 적용을 받습니다. 계약자는 미리 보기에 적용되는 모든 국내 및 국제 수출법과 규정을 준수해야 합니다. 그러한 법에는 수출 대상국, 최종 사용자 및 최종 용도에 대한 제한이 포함됩니다.
-
-14.6 계약자 또는 Google은 상대 당사자의 사전 서면 승인 없이 본 라이선스 계약에서 부여된 권리를 제3자에게 양도하거나 이전할 수 없으며, 그러한 승인 없이 이루어진 양도 시도는 모두 무효입니다. 계약자는 Google의 사전 승인 없이 본 라이선스 계약 상의 책임 또는 의무를 위임할 수 없습니다.
-
-14.7 본 라이선스 계약, 그리고 본 라이선스 계약 상의 계약자와 Google의 관계는 법률 조항 간의 충돌과는 무관하게 캘리포니아주법에 의한 규제를 받습니다. 계약자와 Google은 본 라이선스 계약으로부터 발생하는 모든 법적 문제 해결을 캘리포니아주 산타 클라라(Santa Clara) 카운티 내에 소재한 전속 관할 법원에 의뢰하는 것에 동의합니다. 위 규정에도 불구하고, 계약자는 Google이 여전히 모든 관할권에서 강제 구제책(또는 동등한 유형의 긴급 법적 구제)을 신청할 수 있음에 동의합니다.
-
-
-</div> \ No newline at end of file
diff --git a/docs/html-intl/intl/ko/preview/overview.jd b/docs/html-intl/intl/ko/preview/overview.jd
deleted file mode 100644
index 04febc716544..000000000000
--- a/docs/html-intl/intl/ko/preview/overview.jd
+++ /dev/null
@@ -1,389 +0,0 @@
-page.title=프로그램 개요
-page.metaDescription=Android M 개발자 미리 보기를 시작하신 여러분, 환영합니다. 이 프로그램은 Android의 다음 버전에 대해 앱을 테스트하고 최적화하는 데 필요한 모든 것을 제공해 드립니다.
-page.image=images/cards/card-preview_16-9_2x.png
-page.tags="preview", "developer", "android"
-
-@jd:body
-
-<div class="cols" style=
-"background-color:#ffebc3; padding: 5px 0;margin-bottom:1em; text-align:center;">
-<h3>
- Developer Preview 2 is now available
- </h3>
-
- <ul class="dac-section-links">
- <li class="dac-section-link">
- <a href="{@docRoot}preview/support.html#preview2-notes">
- <span class="dac-sprite dac-auto-chevron"></span>
- Read the Notes</a>
- </li>
-
- <li class="dac-section-link">
- <a href="{@docRoot}preview/support.html#preview2-get">
- <span class="dac-sprite dac-auto-chevron"></span>
- Get the Update</a>
- </li>
-
- <li class="dac-section-link">
- <a href="https://code.google.com/p/android-developer-preview/">
- <span class="dac-sprite dac-auto-chevron"></span>
- Report Issues</a>
- </li>
- </ul>
-</div>
-
-<p>
- <strong>Android M 개발자 미리 보기</strong>를 시작하신 여러분, 환영합니다. 이 프로그램은 Android의 다음 버전에 대해 앱을 테스트하고 최적화하는 데 필요한 모든 것을 제공해 드립니다.
-
- 이 프로그램은 무료이며, M 개발자 미리 보기 도구만 다운로드하면 시작하실 수 있습니다.
-
-</p>
-
-<div style="background-color:#eceff1;padding:1em;">
-<div class="wrap">
- <div class="cols">
- <div class="col-4of12">
- <h5>
- 하드웨어 및 에뮬레이터 시스템 이미지
- </h5>
-
- <p>
- Nexus 5, 6, 9, Player(TV용)와 에뮬레이터에서 앱을 실행하고 테스트해 보세요.
-
- </p>
- </div>
-
- <div class="col-4of12">
- <h5>
- 최신 플랫폼 코드
- </h5>
-
- <p>
- 미리 보기 시행 중에 여러 번의 업데이트를 제공할 예정입니다. 이로써 여러분은 항상 최신 플랫폼 변경에 대해 테스트할 수 있습니다.
-
- </p>
- </div>
-
- <div class="col-4of12">
- <h5>
- 업데이트를 OTA로 전달
- </h5>
-
- <p>
- 일단 기기를 최초 미리 보기에 플래시하고 나면 OTA로 업데이트를 받을 수 있습니다.
-
- </p>
- </div>
- </div>
-
- <div class="cols">
-
-
- <div class="col-4of12">
- <h5>
- 새 동작 및 기능
- </h5>
-
- <p>
- 작업을 일찍 시작하여 새 런타임 권한 모델과 절전 기능 등 새로운 플랫폼 동작을 지원합니다.
-
- </p>
- </div>
-
- <div class="col-4of12">
- <h5>
- 개발자가 보고한 문제에 대한 우선 순위 창
- </h5>
-
- <p>
- Google에서는 처음 몇 주 동안 개발자가 보고한 문제에 우선 순위를 부여할 예정입니다. 가능한 빨리 테스트하고 피드백을 보내 주세요.
-
- </p>
- </div>
-
- <div class="col-4of12">
- <h5>
- 피드백 및 지원
- </h5>
-
- <p>
- 문제를 보고하고 Google의 <a href="https://code.google.com/p/android-developer-preview/">문제 추적기</a>를 사용해 피드백을 보내 주세요.
- <a href="http://g.co/dev/AndroidMDevPreview">M&nbsp;개발자 커뮤니티</a>를 이용하면 다른 개발자들과 의견을 주고받을 수 있습니다.
-
- </p>
- </div>
- </div>
-</div>
-</div>
-
-<!--
-<p>
- With the M Developer Preview, you'll get an early start on testing your apps,
- with enough time to make adjustments before the public platform release later
- in the year. We'll provide several updates to the Preview tools in the weeks
- ahead, so you can keep in sync with the latest changes as the platform moves
- toward launch.
-</p>
-<img src="{@docRoot}preview/images/m-preview-timeline.png" alt=
-"Preview program timeline" id="timeline">
-<p>
- You can help us improve the platform by <a href=
- "https://code.google.com/p/android-developer-preview/">reporting issues</a>
- through our feedback channels. This is especially
- critical in the first month of the preview, when we’ll be giving priority to
- developer-reported issues and feedback.
-</p> -->
-
-
-<h2 id="timeline">
- 일정 및 업데이트
-</h2>
-<img src="{@docRoot}preview/images/m-preview-timeline-crop.png" alt="Preview program timeline" id="timeline">
-<p>
- M 개발자 미리 보기는 5월 28일부터 최종 Android M SDK가 출시될 때까지 실행됩니다. 최종 버전은 2015년 3사분기 중으로 예정된 공개 릴리스 직전에 출시할 계획입니다.
-
-
-</p>
-
-<p>
- 개발 중 중요 단계에 다다를 때마다 여러분의 테스트 기기를 위해 업데이트를 전달해 드리겠습니다.
- 잠정적인 중요 단계는 다음과 같습니다.
-</p>
-
-<ul>
- <li>
- <strong>미리 보기&nbsp;1</strong>(최초 미리 보기 릴리스, 5월 말)
- </li>
-
- <li>
- <strong>미리 보기&nbsp;2</strong>(6월 말/7월 초)
- </li>
-
- <li>
- <strong>미리 보기&nbsp;3</strong>(최종 버전 출시 직전, 7월 말)
- </li>
-</ul>
-
-<p>
- 이러한 업데이트는 <strong>최종 SDK</strong>(3사분기 후반)로 막을 내릴 것이며, 이것으로 Android 새 버전에 대한 공식 API뿐만 아니라 최종 시스템 동작 및 기능도 제공하게 됩니다.
-
-
-</p>
-
-<p>
- Android M에서 테스트와 개발을 수행하는 동안 미리 보기 업데이트가 출시되는 것에 맞춰 <strong>개발 환경을 최신 상태로 유지</strong>할 것을 강력히 권장합니다.
-
- 이 과정을 보다 단순화하기 위해 이미 미리 보기 빌드에 플래시한 기기에는 <strong>OTA(over-the-air) 업데이트</strong>를 제공할 예정이며, 이외에도 수동으로 다운로드하고 플래시할 수 있는 시스템 이미지도 제공할 계획입니다.
-
-
-</p>
-<p class="note">
- <strong>참고:</strong> 최종 SDK와 시스템 이미지는 OTA로 전달할 수 없습니다. 그 대신 개발자 본인의 테스트 기기에서 <strong>수동으로 플래시</strong>해야 합니다.</strong>
-
-
-</p>
-
-<p>
- 미리 보기 업데이트를 이용할 수 있게 될 때마다 <a href="http://android-developers.blogspot.com/">Android 개발자 블로그</a>, 해당 사이트 및 <a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>를 통해서 알려드릴 것입니다.
-
-
-</p>
-
-<h2 id="preview_tools">
- 미리 보기 내용
-</h2>
-
-<p>
- M 개발자 미리 보기에는 기존 앱을 여러 가지 화면 크기, 네트워크 기술, CPU/GPU 칩세트 및 하드웨어 아키텍처에서 테스트하는 데 필요한 모든 것이 포함되어 있습니다.
-
-
-</p>
-
-<h4>
- SDK 도구
-</h4>
-
-<p>
- 이러한 구성 요소는 <a href="{@docRoot}sdk/installing/adding-packages.html">Android Studio</a>에서 SDK Manager를 통해 다운로드할 수 있습니다.
-</p>
-
-<ul>
- <li>M 개발자 미리 보기 <strong>SDK 도구</strong>
- </li>
-
- <li>M 개발자 미리 보기 <strong>에뮬레이터 시스템 이미지</strong>(32비트 및 64비트)
-
- </li>
-
- <li>M 개발자 미리 보기 <strong>Android TV용 에뮬레이터 시스템 이미지</strong>(32비트)
-
- </li>
-</ul>
-
-<h4>
- 하드웨어 시스템 이미지
-</h4>
-
-<p>
- Nexus 기기에 대한 다음과 같은 하드웨어 시스템 이미지는 <a href="download.html">다운로드 페이지</a>에서 다운로드할 수 있습니다.
-
-</p>
-
-<ul>
- <li>
- <strong>Nexus 5</strong>(GSM/LTE) “hammerhead” 기기 시스템 이미지
- </li>
-
- <li>
- <strong>Nexus 6</strong> “shamu” 기기 시스템 이미지
- </li>
-
- <li>
- <strong>Nexus 9</strong>(Wi-Fi) “volantis” 기기 시스템 이미지
- </li>
-
- <li>
- <strong>Nexus Player</strong>(Android TV) “fugu” 기기 시스템 이미지
- </li>
-</ul>
-
-<h4>
- 관련 문서 및 샘플 코드
-</h4>
-
-<p>
- 다음과 같은 관련 문서 리소스는 미리 보기에 대해 익히는 데 유용합니다.
-</p>
-
-<ul>
- <li>
- <a href="setup-sdk.html">SDK 설정</a>에는 시작하는 데 필요한 단계별 지침이 들어 있습니다.
-
- </li>
-
- <li>
- <a href="{@docRoot}preview/testing/guide.html">테스트 가이드</a>와 <a href="behavior-changes.html">동작 변경</a>에서는 테스트해야 할 주요 영역을 알려줍니다.
- </li>
-
- <li>새 API 관련 문서 중에서 <a href="api-overview.html">API 개요</a>, 다운로드할 수 있는 <a href="{@docRoot}preview/download.html#docs">API 참조</a>와 자세한 개발자 가이드(<a href="{@docRoot}preview/features/runtime-permissions.html">권한</a>, <a href="{@docRoot}preview/backup/index.html">앱 백업</a> 등 주요 기능에 대한 내용)도 참조하세요.
-
-
-
-
- </li>
-
- <li>
- <a href="{@docRoot}preview/samples.html">샘플 코드</a>는 권한과 기타 새로운 기능을 지원하는 방법을 설명합니다.
-
- </li>
-
- <li>
- <a href="{@docRoot}preview/support.html#release-notes">릴리스 노트</a>를 보면 M 개발자 미리 보기의 현재 버전에 대해 변경 내용 참고 사항과 차이점 보고서 등 관련 정보를 확인할 수 있습니다.
-
- </li>
-</ul>
-
-<h4>
- 지원 리소스
-</h4>
-
-<p>
- M 개발자 미리 보기에서 테스트하고 개발하는 데 유용한 지원 리소스를 소개합니다.
-
-</p>
-
-<ul>
- <li><a href="https://code.google.com/p/android-developer-preview/">M 개발자 미리 보기 문제 추적기</a>가 여러분의 <strong>기본 피드백 채널</strong>입니다.
-
- 문제 추적기를 통해 버그와 성능 문제를 보고하고 전반적인 피드백을 주시면 됩니다.
- 이를 통해 <a href="https://code.google.com/p/android-developer-preview/wiki/KnownIssues">알려진 문제</a>를 확인하고 해결 방법 단계를 찾아볼 수도 있습니다.
-
- </li>
-
- <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>는 일종의 Google+ 커뮤니티로, 여기에서 여러분은 Android M을 가지고 작업하는 <strong>다른 개발자들과 이야기</strong>를 나눌 수 있습니다. 서로의 의견이나 아이디어를 나누고 Android M 관련 질문에 대한 대답을 찾을 수도 있습니다.
-
-
-
- </li>
-</ul>
-
-
-<h2 id="preview_apis_and_publishing">
- 대상 지정, 미리 보기 API 및 게시
-</h2>
-
-<p>
- Android M 개발자 미리 보기는 개발 전용 릴리스이며 <strong>표준 API 레벨이 없습니다</strong>.
- 앱을 테스트하기 위해 호환성 동작에서 옵트아웃하고자 하는 경우(강력히 권장함), M 개발자 미리 보기를 대상으로 지정하면 됩니다. 앱의 <code><a href=
- "/guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a></code>을 <code>“MNC”</code>로 지정하세요.
-
-
-
-</p>
-
-<p>
- Android M 개발자 미리 보기에서는 <strong>미리 보기 API</strong>를 제공합니다. &mdash;이 API는 최종 SDK가 출시될 때까지 공식적인 버전으로 인정되지 않습니다. 최종 SDK 릴리스는 현재 2015년 삼사분기 무렵으로 예정되어 있습니다.
-
- 이는 즉, 시간이 지나면서 <strong>사소한 API 변경</strong>이 있을 것이라는 점을 예상해야 한다는 뜻입니다. 특히 프로그램 초반 몇 주 동안은 유의해야 합니다.
-
- Android M 개발자 미리 보기를 업데이트할 때마다 변경 내용을 요약해서 제공해 드릴 것입니다.
-
-</p>
-
-<p class="note">
- 미리 보기 API는 변경될 수 있지만, 런타임 권한과 절전 기능과 같은 기본 시스템 동작은 안정적이며 지금 바로 테스트 가능한 상태입니다.
-
-
-</p>
-
-<p>
- 게시에 관해서는, Google Play에서는 <strong>M 개발자 미리 보기를 대상으로 삼는 앱의 게시를 방지합니다.</strong>
- Android M 최종 SDK를 이용할 수 있게 되면 공식 Android M API 레벨을 대상으로 지정할 수 있고, 그때 Google Play에 앱을 게시하면 됩니다.
-
- 그때까지는 테스터들에게 Android M을 대상으로 지정한 앱을 배포하고자 하는 경우 이메일이나 본인의 사이트에서 직접 다운로드를 통해 하시면 됩니다.
-
-
-</p>
-
-<h2 id="get_started">
- 시작 방법
-</h2>
-
-<p>
- 앱 테스트를 시작하려면
-</p>
-
-<ol>
- <li><a href="{@docRoot}preview/api-overview.html">API 개요</a>와 <a href="{@docRoot}preview/behavior-changes.html">동작 변경</a>을 검토해 새로운 내용과 이것이 본인의 앱에 미치는 영향에 대해 알고 있어야 합니다.
-
- 특히, 새로운 <a href="{@docRoot}preview/features/runtime-permissions.html">런타임 권한</a> 모델, 절전 기능과 자동 백업에 대해 숙지하는 것이 좋습니다.
-
-
- </li>
-
- <li>환경을 설정할 때에는 <a href="{@docRoot}preview/setup-sdk.html">미리 보기 SDK 설정</a>과 테스트 기기를 구성하는 데 관련된 지침을 따르세요.
-
-
- </li>
-
- <li><a href="https://developers.google.com/android/nexus/images">플래시 지침</a>을 따라 최신 M 개발자 미리 보기 시스템 이미지를 Nexus 5, 6, 9 및 Player에 플래시하세요.
-
- 일단 개발 기기를 플래시하고 나면, 미리 보기 업데이트가 OTA(over-the-air) 업데이트를 통해 전달됩니다.</a>
-
- </li>
-
- <li><a href="{@docRoot}preview/download.html#docs">M 미리 보기 API 참조</a>와 <a href="{@docRoot}preview/samples.html">M 미리 보기 샘플</a>을 다운로드하면 새로운 API 기능과 앱에서 그러한 기능을 사용하는 방법에 대해 좀 더 자세히 파악할 수 있습니다.
-
-
-
- </li>
-
- <li><a href="http://g.co/dev/AndroidMDevPreview">Android M 개발자 커뮤니티</a>에 가입하여 최신 소식을 알아보고, 새 플랫폼으로 작업하는 다른 개발자들과 이야기를 나눠보세요.
-
-
- </li>
-</ol>
-
-<p>
- Android M 개발자 미리 보기 프로그램에 참가해 주셔서 대단히 감사합니다!
-</p>
diff --git a/docs/html-intl/intl/ko/preview/samples.jd b/docs/html-intl/intl/ko/preview/samples.jd
deleted file mode 100644
index aeb8fc28600d..000000000000
--- a/docs/html-intl/intl/ko/preview/samples.jd
+++ /dev/null
@@ -1,70 +0,0 @@
-page.title=샘플
-page.image=images/cards/samples-new_2x.png
-@jd:body
-
-<p>
- 다음 코드 샘플은 M 개발자 미리 보기를 위해 제공된 것입니다. Android Studio에서 샘플을 다운로드하려면 <b>파일 &gt; 샘플 가져오기</b> 메뉴 옵션을 선택하십시오.
-
-</p>
-
-<p class="note">
- <strong>참고:</strong> 이러한 다운로드 가능한 프로젝트는 Gradle 및 Android Studio와 함께 쓰도록 만들어진 것입니다.
-
-</p>
-
-
-<h3 id="RuntimePermissions">런타임 권한</h3>
-
-<p>
- Android M은 시스템 권한이 작동하는 방식을 확 바꾸어 놓습니다. 사용자는 설치 중이 아니라 런타임에 권한 요청을 승인해 달라는 요청을 받습니다.
- 이 샘플은 이와 같은 권한을 요청하는 방법을 나타낸 것입니다.
-
-</p>
-
-<p><a href="https://github.com/googlesamples/android-RuntimePermissions">GitHub에서 가져오기</a></p>
-
-<h3 id="ConfirmCredentials">확인 자격 증명</h3>
-
-<p>
- 이 샘플은 앱에서 기기 자격 증명을 인증 방법으로 사용하는 법을 나타낸 것입니다.
-</p>
-
-<p><a href="https://github.com/googlesamples/android-ConfirmCredential">GitHub에서 가져오기</a>
-</p>
-
-<h3 id="FingerprintDialog">지문 대화창</h3>
-
-<p>
- 이 샘플은 앱에서 사용자를 인증하기 위해 등록된 지문을 인식하는 방법을 나타낸 것입니다.
-
-</p>
-
-<p><a href="https://github.com/googlesamples/android-FingerprintDialog">GitHub에서 가져오기</a></p>
-
-<h3 id="AutomaticBackup">앱용 자동 백업</h3>
-
-<p>
- Android M은 앱 설정에서 사용할 수 있는 자동 백업을 도입합니다. 이 샘플은 설정 백업을 관리하기 위해 앱에 필터링 규칙을 추가하는 방법을 나타낸 것입니다.
-
-</p>
-
-<p><a href="https://github.com/googlesamples/android-AutoBackupForApps">GitHub에서 가져오기</a></p>
-
-<h3 id="CameraRaw">카메라 2 RAW</h3>
-
-<p>
- <code>Camera2</code> API를 사용해 RAW 카메라 버퍼를 캡처하고 이를 <code>DNG</code> 파일로 저장하는 법을 나타낸 것입니다.
-
-</p>
-
-<p><a href="https://github.com/googlesamples/android-Camera2Raw">GitHub에서 가져오기</a></p>
-
-<h3 id="ActiveNotification">활성 알림</h3>
-
-<p>
- 이 샘플은 <a href="{@docRoot}reference/android/app/NotificationManager.html"><code>NotificationManager</code></a>를 사용하여 앱이 현재 표시하고 있는 알림 수가 몇 개인지 알게 되는 원리를 나타낸 것입니다.
-
-
-</p>
-
-<p><a href="https://github.com/googlesamples/android-ActiveNotifications">GitHub에서 가져오기</a></p>
diff --git a/docs/html-intl/intl/ko/preview/setup-sdk.jd b/docs/html-intl/intl/ko/preview/setup-sdk.jd
deleted file mode 100644
index cf3084b0d735..000000000000
--- a/docs/html-intl/intl/ko/preview/setup-sdk.jd
+++ /dev/null
@@ -1,207 +0,0 @@
-page.title=미리 보기 SDK 설정하기
-page.image=images/cards/card-set-up_16-9_2x.png
-
-@jd:body
-
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#get-as13">Android Studio 1.3 가져오기</a></li>
- <li><a href="#get-sdk">미리 보기 SDK 가져오기</a></li>
- <li><a href="#create-update">프로젝트 생성 또는 업데이트</a></li>
- <li><a href="#setup-test">테스트를 위해 설정</a></li>
- </ol>
- </div>
-</div>
-
-<p>M 개발자 미리 보기 SDK는 Android SDK Manager에서 이용할 수 있습니다. 이 문서에서는 독자 여러분이 Android 앱 개발, 예를 들어 Android SDK Manager 사용이나 프로젝트 생성 등에 익숙하다고 가정합니다.
-
- Android를 처음 사용하시는 경우, 우선 <a href="{@docRoot}training/basics/firstapp/index.html">첫 앱 구축하기</a> 학습 단원부터 참조하십시오.</a>
-
-</p>
-
-<h2 id="get-as13">Android Studio 1.3 가져오기</h2>
-
-<p>개발자 미리 보기는 역시 미리 보기 상태인 Android Studio 1.3과 함께 사용하는 것이 가장 좋습니다.
- Android Studio 1.3의 미리 보기 버전을 설치하여 미리 보기 SDK 작업에 사용하는 것을 적극 추천합니다.
-</p>
-
-<p class="caution"><strong>주의:</strong> Android Studio 1.3의 카나리아 미리 보기는 아직도 활발히 개발 중인 상태입니다.
- 기본 개발 머신을 사용하여 개발자 미리 보기를 테스트하는 경우, 두 번째 Android Studio 설치를 하나 더 생성해 테스트에 사용하면 됩니다.
-
-</p>
-
-<p>Android Studio 1.3 미리 보기를 설치하려면 다음과 같이 하면 됩니다.</p>
-
-<ol>
- <li><a href="{@docRoot}tools/studio/index.html">Android Studio</a>를 다운로드하여 시작합니다.
-
- </li>
-
- <li><strong>설정</strong> 창을 엽니다(또는 Windows의 경우 <strong>파일 &gt; 설정</strong>을 선택해도 됩니다).
- <strong>외관 및 동작 &gt; 시스템 &gt; 설정 &gt; 업데이트</strong> 패널을 선택하십시오.
-
-
-
- <p class="aside">OSX의 경우, <strong>외관 및 동작</strong> 패널은 Android Studio의 <strong>기본 설정</strong> 창에 있습니다.
-
-</p>
- </li>
-
- <li> <strong>업데이트</strong> 패널에서 <strong>다음에 대해 업데이트 자동 확인:
- Canary 채널</strong>이라는 선택 사항을 선택합니다.
- </li>
-
- <li><strong>업데이트</strong> 패널에서 <strong>지금 확인</strong>을 선택하여 최신 카나리아 빌드를 확인합니다.
- 메시지가 표시되면 빌드를 다운로드하고 설치하십시오.
-
- </li>
-</ol>
-
-<h2 id="get-sdk">미리 보기 SDK 가져오기</h2>
-
-<p>개발 환경에 미리 보기 SDK 구성 요소를 추가하려면 다음과 같이 하면 됩니다.</p>
-
-<ol>
- <li>Android Studio 1.3 미리 보기를 시작합니다.
- </li>
-
- <li><strong>설정</strong> 창을 엽니다(또는 Windows의 경우 <strong>파일 &gt; 설정</strong>을 선택해도 됩니다).
- <strong>외관 및 동작 &gt; 시스템 &gt; 설정 &gt; 업데이트</strong> 패널을 선택하십시오.
-
-
-
- <p class="aside">OSX의 경우, <strong>외관 및 동작</strong> 패널은 Android Studio의 <strong>기본 설정</strong> 창에 있습니다.
-
-</p>
- </li>
-
- <li><strong>업데이트</strong> 패널에서 <strong>다음에 대해 업데이트 자동 확인:
- Canary 채널</strong> 및 <strong>Android SDK에 대한 업데이트 자동 확인:
- 미리 보기 채널</strong> 선택 사항을 선택합니다.
- </li>
-
- <li><strong>Android SDK Manager</strong>를 시작합니다 (Android Studio 1.3에서는 SDK Manager가 독립 실행형 애플리케이션이 아니고 Android Studio에 통합되어 있습니다).
-
-
- </li>
-
- <li><strong>플랫폼</strong> 섹션 아래에서 <strong>Android MNC 미리 보기</strong>를 선택하십시오.
-
- </li>
-
- <li><strong>도구</strong> 섹션에서 최신 Android <strong>SDK 도구</strong>, <strong>플랫폼-도구</strong>, 및 <strong>빌드-도구</strong>를 선택합니다.
-
-
- </li>
-
- <li><strong>패키지 설치</strong>를 클릭하고 패키지 전체에 대해 라이선스 사용 계약을 수락합니다.
-
- </li>
-
- <li>M 개발자 미리 보기가 설치되었는지 확인하려면 <strong>설정</strong> 창을 열고 <strong>외관 및 동작 &gt; 시스템 설정 &gt; Android SDK</strong> 패널을 선택하면 됩니다.
-
-</li>
-
- <li><strong>Android SDK</strong> 패널에서 <strong>SDK 플랫폼</strong> 탭을 선택합니다.
- <strong>Android MNC 미리 보기</strong>가 <em>설치됨</em> 아래 목록으로 나열되어 있는 것이 정상입니다.
- 또한, <strong>SDK 도구</strong> 탭을 열어 최신 도구가 설치되었는지 확인하십시오.
-
-
- </li>
-</ol>
-<p>이러한 단계를 완료하고 나면 미리 보기 구성 요소를 본인의 개발 환경에서 이용할 수 있습니다.
- </p>
-
-
-<h2 id="create-update">프로젝트 생성 또는 업데이트</h2>
-
-<p>
- 미리 보기 API를 사용하려면 개발 프로젝트를 하나 생성하거나 업데이트하여 미리 보기 구성 요소를 사용해야 합니다.
-
-</p>
-
-
-<h3 id="create">새 프로젝트 생성하기</h3>
-
-<p>
- 미리 보기로 프로젝트를 생성하려면 Android Studio를 사용할 것을 권장합니다. <a href="{@docRoot}sdk/installing/create-project.html">프로젝트 생성하기</a>에 설명되어 있는 단계를 쭉 따라가다 보면 프로젝트 마법사의 <em>폼 팩터</em> 화면에 도달합니다.
-
- 그러면 다음과 같은 단계를 따라 미리 보기에 맞게 구성된 프로젝트를 생성하면 됩니다.
-
-</p>
-
-<ul>
- <li><strong>전화기 및 태블릿</strong>을 확인합니다.</li>
- <li><strong>MNC: Android M(미리 보기)</strong>를 선택합니다. 이것은 <strong>최소 SDK</strong> 안에 있습니다.
-</li>
-</ul>
-
-
-<h3 id="update">기존 프로젝트 업데이트</h3>
-
-<p>
- 기존 프로젝트의 경우, 미리 보기 API를 활성화하려면 프로젝트 구성을 수정해야 합니다. 개발 환경에서 본인의 모듈에 대한 <code>build.gradle</code> 파일을 열고 다음의 값을 다음과 같이 설정합니다.
-
-
-</p>
-
-<ul>
- <li><code>compileSdkVersion</code>을 <code>'android-MNC'</code>로 설정</li>
- <li><code>minSdkVersion</code>을 <code>'MNC'</code>로 설정</li>
- <li><code>targetSdkVersion</code>을 <code>'MNC'</code>로 설정</li>
-</ul>
-
-
-<h2 id="setup-test">테스트를 위해 설정</h2>
-
-<p>
- 앱을 미리 보기로 테스트하려면 플랫폼의 미리 보기 버전으로 구성한 기기 또는 가상 기기가 있어야 합니다.
- 호환되는 기기를 가지고 있으면 미리 보기 플랫폼을 설치하여 테스트에 쓰면 됩니다.
- 그렇지 않은 경우, 가상 기기를 구성하여 테스트에 사용할 수도 있습니다.
-</p>
-
-<h3 id="setup-device">물리적 기기 설정</h3>
-
-<p>
- Nexus 5, Nexus 6, Nexus 9 또는 Android TV를 가지고 있는 경우, 이들 기기에 미리 보기 시스템 이미지를 설치하여 앱을 테스트하는 데 쓸 수 있습니다. 플랫폼의 미리 보기 버전으로 가상 기기를 설정하려면 Android Studio 내에서 해당 버전을 다운로드하면 됩니다. 이때 Android 가상 기기 관리자 도구를 사용하십시오.
-
-
-
-</p>
-
-<p class="caution">
- <strong>중요:</strong> 기기에 미리 보기 이미지를 설치하면 <em>기기에서 모든 데이터를 제거하므로</em>, 미리 보기 이미지를 설치하기에 앞서 데이터를 모두 백업하는 것이 좋습니다.
-
-</p>
-
-<h3 id="setupAVD">가상 기기 설정</h3>
-
-<p>
- 플랫폼의 미리 보기 버전으로 가상 기기를 설정하려면 Android Studio 내에서 해당 버전을 다운로드하면 됩니다. 이때 Android 가상 기기 관리자 도구를 사용하십시오.
-
-</p>
-
-<p>AVD Manager로 AVD를 생성하려면 다음과 같이 하면 됩니다.</p>
-
-<ol>
- <li><a href="{@docRoot}preview/setup-sdk.html">미리 보기 SDK 설정하기</a>에 설명된 바에 따라 개발 환경에 미리 보기 SDK를 설치합니다.
-
-</li>
- <li><a href="{@docRoot}tools/devices/managing-avds.html">AVD Manager로 AVD 관리하기</a>에 나온 단계를 따르십시오.
-
- 다음과 같은 설정을 사용하면 됩니다.
- <ul>
- <li><strong>기기:</strong> Nexus 5, Nexus 6, Nexus 9 또는 Android TV</li>
- <li><strong>대상:</strong>
- Android M(미리 보기) - API 레벨 M</li>
- <li><strong>ABI:</strong> x86</li>
- </ul>
- </li>
-</ol>
-
-<p>
- 테스트를 위해 가상 기기를 생성하는 데 대한 자세한 정보는 <a href="{@docRoot}tools/devices/index.html">가상 기기 관리하기</a>를 참조하십시오.
-</p>
diff --git a/docs/html-intl/intl/ko/preview/testing/guide.jd b/docs/html-intl/intl/ko/preview/testing/guide.jd
deleted file mode 100644
index 7f1707107e69..000000000000
--- a/docs/html-intl/intl/ko/preview/testing/guide.jd
+++ /dev/null
@@ -1,187 +0,0 @@
-page.title=테스트 가이드
-page.image=images/cards/card-build_16x9_2x.png
-page.keywords=previewresources,androidm,testing,permissions
-
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#runtime-permissions">권한 테스트</a></li>
- <li><a href="#doze-standby">Doze 및 앱 대기 모드 테스트</a></li>
- <li><a href="#ids">자동 백업 및 기기 식별자</a></li>
- </ol>
- </div>
-</div>
-
-<p>
- Android M 개발자 미리 보기에서는 앱이 플랫폼의 다음 버전에서 제대로 작동할 것인지 확인해볼 기회를 부여합니다.
- 이 미리 보기에는 앱에 영향을 미칠 수 있는 수많은 API와 동작 변경 내용이 포함되어 있습니다.이 내용은 <a href="{@docRoot}preview/api-overview.html">API 개요</a>와 <a href="{@docRoot}preview/behavior-changes.html">동작 변경</a>에 설명해 놓았습니다.
-
- 미리 보기로 앱을 테스트할 때에는 사용자에게 좋은 환경을 제공하기 위해 개발자 여러분이 꼭 주안점을 두어야 할 몇 가지 특정한 시스템 변경 내용이 있습니다.
-
-
-</p>
-
-<p>
- 이 가이드는 앱에서 테스트할 미리 보기 기능은 어떤 것이고, 테스트 방법은 어떤지에 대해 설명한 것입니다. 이와 같은 특정 미리 보기 기능을 먼저 테스트하는 것이 좋습니다. 이들은 앱의 동작에 미치는 영향이 클 가능성이 높기 때문입니다.
-
-
-</p>
-
-<ul>
- <li><a href="#runtime-permissions">권한</a>
- </li>
- <li><a href="#doze-standby">Doze 및 앱 대기 모드</a>
- </li>
- <li><a href="#ids">자동 백업 및 기기 식별자</a></li>
-</ul>
-
-<p>
- 테스트용 미리 보기 시스템 이미지로 기기 또는 가상 기기를 설정하는 방법에 대한 자세한 정보는 <a href="{@docRoot}preview/setup-sdk.html">미리 보기 SDK 설정하기</a>를 참조하십시오.
-
-</p>
-
-
-<h2 id="runtime-permissions">권한 테스트</h2>
-
-<p>
- 새로운 <a href="{@docRoot}preview/features/runtime-permissions.html">권한</a> 모델은 사용자가 여러분의 앱에 권한을 할당하는 방법을 바꿔 놓습니다.
- 설치 절차 중에 모든 권한을 허용하는 것이 아니라, 앱이 런타임에 사용자에게 각각의 권한을 요청해야 합니다.
-
- 사용자 입장에서는 이러한 동작으로 각 앱의 액티비티에 대해 더 세분화된 제어권을 행사할 수 있을 뿐만 아니라 이 앱이 어째서 특정한 권한을 요청하고 있는 것인지 맥락을 더 잘 이해할 수 있게 되기도 합니다.
- 사용자는 언제든 앱에 개별적으로 권한을 허용할 수 있고, 이를 취소할 수도 있습니다.
- 미리 보기의 이러한 기능은 앱의 동작에 영향을 미칠 가능성이 가장 높고, 앱의 몇 가지 기능이 작동하지 않도록 막거나 저하된 상태로 작동하게 할 수도 있습니다.
-
-
-</p>
-
-<p class="caution">
- 이 변경 내용은 새 플랫폼에서 실행되는 모든 앱에 영향을 비치며, 새 플랫폼 버전을 대상으로 하지 않는 앱도 예외가 아닙니다.
- 레거시 앱에 대해 플랫폼이 제한된 호환성 동작을 제공하기는 하지만, 지금 바로 새 권한 모델로 앱의 마이그레이션 계획을 시작하는 편이 좋습니다. 플랫폼이 공식적으로 출시될 때에 맞춰 앱의 업데이트된 버전을 게시하는 것을 목표로 하십시오.
-
-
-</p>
-
-
-<h3 id="permission-test-tips">테스트 팁</h3>
-
-<p>
- 다음은 새 권한 동작에 대해 앱 테스트를 계획하고 실행하는 데 유용한 몇 가지 테스트 팁입니다.
-
-</p>
-
-<ul>
- <li>앱의 현재 권한과 관련된 코드 경로를 확인합니다.</li>
- <li>권한 보호된 서비스 및 데이터 전반에 걸친 사용자 흐름을 테스트합니다.</li>
- <li>허용된/취소된 권한을 여러 가지로 조합하여 테스트합니다.</li>
- <li>명령줄에서 권한을 관리할 때 {@code adb} 도구를 사용합니다.
- <ul>
- <li>권한과 상태를 그룹별로 목록으로 나열합니다.
- <pre>adb shell pm list permissions -d -g</pre>
- </li>
- <li>하나 이상의 권한을 다음과 같은 구문을 사용하여 허용하거나 취소합니다.<br>
- <pre>adb shell pm [grant|revoke] &lt;permission.name&gt; ...</pre>
- </li>
- </ul>
- </li>
- <li>권한을 사용하는 서비스에 대해 앱을 분석해봅니다.</li>
-</ul>
-
-<h3 id="permission-test-strategy">테스트 전략</h3>
-
-<p>
- 권한을 변경하면 앱의 구조와 디자인은 물론 사용자 환경과, 개발자가 사용자에게 제공하는 흐름에도 영향을 미칩니다.
- 앱의 현재 권한 사용 내용을 평가한 다음 제공하고자 하는 새로운 흐름을 계획하기 시작해야 합니다.
- 플랫폼의 공식 릴리스에서 호환성 동작을 제공할 예정이지만, 이와 같은 동작에만 의존하지 말고 앱 업데이트를 계획하는 것이 좋습니다.
-
-
-</p>
-
-<p>
- 앱이 실제로 필요로 하고 사용하는 권한을 확인한 다음, 권한 보호된 서비스를 사용하는 여러 가지 코드 경로를 찾습니다.
- 이렇게 하려면 새 플랫폼에서 여러 가지로 조합한 테스트를 거치고 코드 분석을 통해야 합니다.
- 테스트에서는 런타임 권한에 옵트인하는 것에 주안점을 두는 것이 좋습니다. 앱의 {@code targetSdkVersion}을 미리 보기 버전으로 변경하세요.
- 자세한 정보는 <a href="{@docRoot}preview/setup-sdk.html#">미리 보기 SDK 설정하기</a>를 참조하십시오.
-
-</p>
-
-<p>
- 불러내고 추가한 여러 가지 권한들을 다양하게 조합해서 테스트해보면 권한에 좌우되는 사용자 흐름을 강조할 수 있습니다.
- 종속성이 분명하지 않거나 논리적인 경우, 리팩터링을 고려해 보거나 해당 흐름을 구분하여 종속성을 제거, 또는 해당 권한이 왜 필요한지 분명히 하는 방안을 고려해야 합니다.
-
-
-</p>
-
-<p>
- 런타임 권한의 동작, 테스트 및 모범 사례에 대한 자세한 정보는 <a href="{@docRoot}preview/features/runtime-permissions.html">권한</a> 개발자 미리 보기 페이지를 참조하십시오.
-
-
-</p>
-
-
-<h2 id="doze-standby">Doze 및 앱 대기 모드 테스트</h2>
-
-<p>
- Doze 및 앱 대기 모드의 절전 기능은 기기가 유휴 상태에 있을 때 또는 사용자가 앱에 초점을 맞추고 있지 않을 때 앱이 수행할 수 있는 배경 처리의 양을 제한합니다.
- 시스템이 앱에 부과할 수 있는 제한 사항에는 네트워크 액세스를 제한하거나 없애기, 배경 작업을 일시 중지시키기, 알림 일시 중지, 절전 모드 해제 및 알람 요청 무시 등이 포함됩니다.
-
- 이러한 절전 기능에 앱이 적절히 동작하도록 확실히 해 두려면 이와 같은 저전력 상태를 시뮬레이트하여 앱을 테스트해보아야 합니다.
-
-
-</p>
-
-<h4 id="doze">앱에서 Doze 테스트하기</h4>
-
-<p>앱으로 Doze 기능을 테스트하려면 다음과 같이 하면 됩니다.</p>
-
-<ol>
-<li>하드웨어 기기 또는 가상 기기를 M 미리 보기 시스템 이미지로 구성합니다.</li>
-<li>기기를 개발 머신에 연결시키고 앱을 설치합니다.</li>
-<li>앱을 실행시킨 다음 활성 상태로 그냥 둡니다.</li>
-<li>기기가 Doze 모드에 들어가는 것을 시뮬레이트하려면 다음 명령을 실행하십시오.
-
-<pre>
-$ adb shell dumpsys battery unplug
-$ adb shell dumpsys deviceidle step
-$ adb shell dumpsys deviceidle -h
-</pre>
-
- </li>
- <li>기기가 다시 활성화되면 앱이 어떻게 동작하는지 살펴보십시오. 기기가 Doze 모드를 종료할 때 정상적으로 복구되는지 확인해야 합니다.
-</li>
-</ol>
-
-
-<h4 id="standby">앱에서 앱 대기 모드 테스트하기</h4>
-
-<p>앱으로 앱 대기 모드를 테스트하려면 다음과 같이 하면 됩니다.</p>
-
-<ol>
- <li>하드웨어 기기 또는 가상 기기를 M 미리 보기 시스템 이미지로 구성합니다.</li>
- <li>기기를 개발 머신에 연결시키고 앱을 설치합니다.</li>
- <li>앱을 실행시킨 다음 활성 상태로 그냥 둡니다.</li>
- <li>앱이 대기 모드에 들어가는 것을 시뮬레이트하려면 다음 명령을 실행하십시오.
-
-<pre>
-$ adb shell am broadcast -a android.os.action.DISCHARGING
-$ adb shell am set-idle &lt;packageName&gt; true
-</pre>
-
- </li>
- <li>앱이 절전 모드 해제되는 상태를 시뮬레이트하려면 다음 명령을 사용하면 됩니다.
- <pre>$ adb shell am set-idle &lt;packageName&gt; false</pre>
- </li>
- <li>앱이 절전 모드에서 해제되면서 어떻게 동작하는지 살펴보십시오. 대기 모드에서 정상적으로 복구되는지 확인해야 합니다.
- 특히, 앱의 알림과 배경 작업이 계속 예상했던 대로 기능하는지 확인해야 합니다.
-</li>
-</ol>
-
-<h2 id="ids">앱용 자동 백업 및 기기별 식별자</h2>
-
-<p>앱이 내부 저장소에서 각 기기에 따라 다른 식별자를 유지하는 경우(예: Google Cloud 메시지 등록 ID), 모범 사례를 따라 저장소 위치를 자동 백업에서 배제해야 합니다. 이 내용은 <a href="{@docRoot}preview/backup/index.html">앱용 자동 백업</a>에 설명되어 있습니다.
-
-
-
- </p>
diff --git a/docs/html-intl/intl/ko/preview/testing/performance.jd b/docs/html-intl/intl/ko/preview/testing/performance.jd
deleted file mode 100644
index ce2bf27bbfc1..000000000000
--- a/docs/html-intl/intl/ko/preview/testing/performance.jd
+++ /dev/null
@@ -1,656 +0,0 @@
-page.title=표시 성능 테스트
-page.image=images/cards/card-test-performance_2x.png
-page.keywords=성능, FPS, 도구
-
-@jd:body
-
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>이 문서의 내용</h2>
- <ol>
- <li><a href="#measure">UI 성능 측정</a>
- <ul>
- <li><a href="#aggregate">프레임 상태 집계</a></li>
- <li><a href="#timing-info">정확한 프레임 타이밍 정보</a></li>
- <li><a href="#timing-dump">단순한 프레임 타이밍 덤프</a></li>
- <li><a href="#collection-window">상태 수집 창 제어</a></li>
- <li><a href="#diagnose">성능 저하 진단</a></li>
- <li><a href="#resources">추가 리소스</a></li>
- </ul>
- </li>
- <li><a href="#automate">UI 성능 테스트 자동화</a>
- <ul>
- <li><a href="#ui-tests">UI 테스트 설정</a></li>
- <li><a href="#automated-tests">자동화된 UI 테스트 설정</a></li>
- <li><a href="#triage">관측된 문제 심사 및 수정</a></li>
- </ul>
- </li>
- </ol>
- </div>
-</div>
-
-
-<p>
- 사용자 인터페이스(UI) 성능 테스트를 수행하면 앱이 기능적인 요건에 부합할 뿐만 아니라 사용자가 앱과 부드럽고 매끈하게 상호작용하며 초당 60 프레임의 일관된 속도로(<a href="https://www.youtube.com/watch?v=CaMTIgxCSqU&amp;index=25&amp;list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">왜 60fps일까요?</a>) 생략되거나 지연된 프레임, 또는 전문 용어로 <em>jank</em>(프레임이 넘어가는 현상)가 없이 실행되게 보장할 수 있습니다.
-
-
- 이 문서에서는 UI 성능을 측정하는 데 사용할 수 있는 몇 가지 도구를 설명하고, 테스트 방법에 UI 성능 측정법을 통합하는 데 쓰이는 접근법을 보여드립니다.
-
-
-</p>
-
-
-<h2 id="measure">UI 성능 측정</h2>
-
-<p>
- 성능을 개선하려면 우선 시스템의 성능을 측정할 수 있는 능력부터 갖추고, 그 다음에 파이프라인의 여러 부분에서 나올 수 있는 다양한 문제를 진단하고 식별해야 합니다.
-
-
-</p>
-
-<p>
- <em><a href="https://source.android.com/devices/tech/debug/dumpsys.html">dumpsys</a></em>는 Android 도구의 일종으로 기기에서 실행되면서 시스템 서비스의 상태에 대한 흥미로운 정보를 덤프하는 역할을 합니다.
-
- <em>gfxinfo</em> 명령을 dumpsys에 전달하면 기록 단계 중에 발생하는 애니메이션 프레임과 관련된 성능 정보가 담긴 logcat으로 출력을 제공합니다.
-
-
-</p>
-
-<pre>
-&gt; adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt;
-</pre>
-
-<p>
- 이 명령은 프레임 타이밍 데이터의 서로 다른 변형을 여러 개 작성할 수 있습니다.
-</p>
-
-<h3 id="aggregate">프레임 상태 집계</h3>
-
-<p>
- M 미리 보기에서 이 명령은 프레임 데이터의 집계된 분석을 logcat으로 출력합니다. 이는 프로세스의 전 수명을 통틀어 수집한 것입니다.
- 예를 들면 다음과 같습니다.
-</p>
-
-<pre class="noprettyprint">
-Stats since: 752958278148ns
-Total frames rendered: 82189
-Janky frames: 35335 (42.99%)
-90th percentile: 34ms
-95th percentile: 42ms
-99th percentile: 69ms
-Number Missed Vsync: 4706
-Number High input latency: 142
-Number Slow UI thread: 17270
-Number Slow bitmap uploads: 1542
-Number Slow draw: 23342
-</pre>
-
-<p>
- 이와 같은 높은 레벨의 통계는 레벨이 높을 때 앱의 렌더링 성능을 나타내며, 이외에도 여러 프레임에 걸친 앱의 안정성을 나타내기도 합니다.
-
-</p>
-
-
-<h3 id="timing-info">정확한 프레임 타이밍 정보</h3>
-
-<p>
- M 미리 보기에서는 gfxinfo에 사용할 수 있는 새 명령어를 도입했습니다. 바로 <em>framestats</em>로, 이는 최근 프레임으로부터 극히 상세한 프레임 타이밍 정보를 제공하여 문제를 더욱 정확하게 추적하고 디버그할 수 있습니다.
-
-
-</p>
-
-<pre>
-&gt;adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt; framestats
-</pre>
-
-<p>
- 이 명령은 프레임 타이밍 정보를 나노초 타임스탬프로 출력하며, 그 출처는 앱이 만든 마지막 120개의 프레임입니다. 아래는 adb dumpsys gfxinfo
- &lt;PACKAGE_NAME&gt; framestats에서 가져온 원시 출력을 예로 나타낸 것입니다.
-
-</p>
-
-<pre class="noprettyprint">
-0,49762224585003,49762241251670,9223372036854775807,0,49762257627204,49762257646058,49762257969704,49762258002100,49762265541631,49762273951162,49762300914808,49762303675954,
-0,49762445152142,49762445152142,9223372036854775807,0,49762446678818,49762446705589,49762447268818,49762447388037,49762453551527,49762457134131,49762474889027,49762476150120,
-0,49762462118845,49762462118845,9223372036854775807,0,49762462595381,49762462619287,49762462919964,49762462968454,49762476194547,49762476483454,49762480214964,49762480911527,
-0,49762479085548,49762479085548,9223372036854775807,0,49762480066370,49762480099339,49762481013089,49762481085850,49762482232152,49762482478350,49762485657620,49762486116683,
-</pre>
-
-<p>
- 이 출력의 각 줄은 앱이 만든 프레임을 나타냅니다. 각 줄에는 정해진 숫자의 열이 있으며 이 열은 프레임 제작 파이프라인의 각 단계에서 소요한 시간을 나타냅니다.
- 다음 섹션에서는 각 열이 무엇을 나타내는지 등, 이 형식에 대해 좀 더 자세히 다뤄보겠습니다.
-
-</p>
-
-
-<h4 id="fs-data-format">Framestats 데이터 형식</h4>
-
-<p>
- 데이터 블록은 CSV 형식으로 출력되기 때문에 이를 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하기 등의 작업이 매우 단도직입적입니다.
- 다음 표는 출력 데이터 열의 형식을 설명한 것입니다.
- 타임스탬프는 모두 나노초 단위입니다.
-</p>
-
-<ul>
- <li>플래그
- <ul>
- <li>플래그 열에 '0'이 기재되어 있는 행의 경우, 총 프레임 시간을 계산하려면 FRAME_COMPLETED 열에서 INTENDED_VSYNC 열을 빼면 됩니다.
-
- </li>
-
- <li>이것이 0이 아니면 그 행은 무시해야 합니다. 해당 프레임이 정상 성능의 이상값인 것으로 판별되었기 때문이며, 여기에서는 레이아웃과 그리기에 16ms 이상이 걸릴 것으로 예상됩니다.
-
- 다음은 이런 일이 일어나는 몇 가지 이유입니다.
- <ul>
- <li>창 레이아웃이 변경되었습니다(애플리케이션의 첫 프레임 또는 한 회 회전 이후).
-
- </li>
-
- <li>프레임을 건너뛰었을 가능성도 있습니다. 이 경우 몇몇 값에 가비지 타임스탬프가 있을 것입니다.
- 프레임을 건너뛰는 것은 해당 프레임이 60fps를 초과하는 경우 또는 화상에 나타난 것 중 아무 것도 변한 것이 없을 때 등이며, 이는 반드시 앱에 문제가 있음을 나타내는 징후는 아닙니다.
-
-
- </li>
- </ul>
- </li>
- </ul>
- </li>
-
- <li>INTENDED_VSYNC
- <ul>
- <li>프레임에 대한 원래 의도한 시작 지점입니다. 이 값이 VSYNC와 다른 경우, UI 스레드에서 발생한 작업이 있어 이것이 vsync 신호에 적절한 시간 내에 응답하지 못하도록 한 것입니다.
-
-
- </li>
- </ul>
- </li>
-
- <li>VSYNC
- <ul>
- <li>Vsync 수신기 전체와 프레임에 대한 드로잉에서 사용된 시간 값입니다.(Choreographer 프레임 콜백, 애니메이션, View.getDrawingTime() 등)
-
- </li>
-
- <li>VSYNC와 이것이 애플리케이션에 미치는 영향에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=1iaHxmfZGGc&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=23">VSYNC 이해하기</a> 비디오를 확인하십시오.
-
-
- </li>
- </ul>
- </li>
-
- <li>OLDEST_INPUT_EVENT
- <ul>
- <li>입력 대기열에서 가장 오래된 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다.
-
- </li>
-
- <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다.
-
- </li>
- </ul>
- </li>
-
- <li>NEWEST_INPUT_EVENT
- <ul>
- <li>입력 대기열에서 가장 최근 입력 이벤트의 타임스탬프 또는 프레임에 대한 입력 이벤트가 없는 경우 Long.MAX_VALUE입니다.
-
- </li>
-
- <li>이 값은 기본적으로 플랫폼 작업을 위해 의도된 것이며 앱 개발자에게는 한정된 정도로 유용한 값입니다.
-
- </li>
-
- <li>다만 앱이 얼마나 긴 대기 시간을 추가하고 있는지를 대략적으로 알아볼 수는 있습니다. (FRAME_COMPLETED - NEWEST_INPUT_EVENT)를 살펴보면 됩니다.
-
- </li>
- </ul>
- </li>
-
- <li>HANDLE_INPUT_START
- <ul>
- <li>입력 이벤트가 애플리케이션에 발송된 시점의 타임스탬프입니다.
- </li>
-
- <li>이것과 ANIMATION_START 사이의 시간을 보면 애플리케이션이 입력 이벤트를 처리하느라 보낸 시간을 측정할 수 있습니다.
-
- </li>
-
- <li>이 숫자가 크면(2ms 초과) 이는 앱이 입력 이벤트를 처리하느라 보기 드물게 긴 시간을 소요한다는 뜻입니다. 예를 들어 View.onTouchEvent()는 이 작업을 최적화해야 하거나 다른 스레드로 오프로드해야 한다는 뜻일 수 있습니다.
-
- 다른 시나리오도 몇 가지 있을 수 있다는 점을 유의하십시오. 예를 들어 새 액티비티를 시작하는 클릭 이벤트나 그와 비슷한 것의 경우, 이 숫자가 클 것을 예상하고 받아들일 수 있습니다.
-
-
- </li>
- </ul>
- </li>
-
- <li>ANIMATION_START
- <ul>
- <li>Choreographer에 등록된 애니메이션이 실행된 시점의 타임스탬프입니다.
- </li>
-
- <li>이것과 PERFORM_TRANVERSALS_START 사이의 시간을 보면 실행 중인 애니메니터 전체((ObjectAnimator, ViewPropertyAnimator 및 Transitions가 보편적인 것들임)를 평가하는 데 시간이 얼마나 걸렸는지 판단할 수 있습니다.
-
-
- </li>
-
- <li>이 숫자가 크면(2ms 초과), 앱이 사용자 지정 애니메이터를 작성한 적이 있는지 확인하십시오. 아니면 ObjectAnimators가 애니메이션 효과를 실행하는 필드가 어느 것인지 알아보고 이들이 애니메이션에 대해 적절한지 확인해야 합니다.
-
-
- </li>
-
- <li>Choreographer에 대한 자세한 정보는 <a href="https://developers.google.com/events/io/sessions/325418001">버터거나 나쁘거나(For Butter or Worse)</a> 비디오를 참조하십시오.
-
- </li>
- </ul>
- </li>
-
- <li>PERFORM_TRAVERSALS_START
- <ul>
- <li>이 값에서 DRAW_START를 빼면 레이아웃과 측정 단계를 완료하는 데 얼마나 걸렸는지 추출할 수 있습니다(스크롤 또는 애니메이션 중에는 이 값이 0에 가까울 것이라는 예상이 나와야 한다는 점을 유의하십시오).
-
-
- </li>
-
- <li>렌더링 파이프라인의 측정 및 레이아웃 단계에 대한 자세한 정보는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오.
-
-
- </li>
- </ul>
- </li>
-
- <li>DRAW_START
- <ul>
- <li>PerformTraversals의 그리기 단계가 시작된 시점입니다. 이것은 무효화된 모든 보기의 표시 목록을 기록하는 시작 지점입니다.
-
- </li>
-
- <li>이것과 SYNC_START 사이의 시간이 트리의 모든 무효화된 보기에서 View.draw()를 호출하는 데 걸린 시간입니다.
-
- </li>
-
- <li>드로잉 모델에 대한 자세한 정보는 <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#hardware-model">하드웨어 가속</a> 또는 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&amp;index=27">무효화, 레이아웃 및 성능</a> 비디오를 참조하십시오.
-
-
- </li>
- </ul>
- </li>
-
- <li>SYNC_START
- <ul>
- <li>드로잉의 동기화 단계가 시작된 시점입니다.
- </li>
-
- <li>이것과 ISSUE_DRAW_COMMANDS_START 사이의 시간이 상당히 큰 값인 경우(0.4ms 초과 또는 그와 유사), 일반적으로 새로운 비트맵이 많이 그려져서 이를 GPU에 업로드해야 한다는 뜻입니다.
-
-
- </li>
-
- <li>동기화 단계에 대해 더 자세히 알아보려면 <a href="https://www.youtube.com/watch?v=VzYkVL1n4M8&amp;index=24&amp;list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu">프로필 GPU 렌더링</a> 비디오를 참조하십시오.
-
- </li>
- </ul>
- </li>
-
- <li>ISSUE_DRAW_COMMANDS_START
- <ul>
- <li>하드웨어 렌더러가 GPU에 드로잉 명령을 발행하기 시작한 시점입니다.
- </li>
-
- <li>이것과 FRAME_COMPLETED 사이의 시간을 보면 앱이 얼마나 많은 GPU 작업을 생성하고 있는지 대략적으로 알 수 있습니다.
- Overdraw가 너무 많거나 렌더링 효과가 비효율적인 것 등의 문제가 여기에 나타납니다.
-
- </li>
- </ul>
- </li>
-
- <li>SWAP_BUFFERS
- <ul>
- <li>EglSwapBuffers가 호출된 시점으로, 플랫폼 작업 외에는 비교적 흥미롭지 않습니다.
-
- </li>
- </ul>
- </li>
-
- <li>FRAME_COMPLETED
- <ul>
- <li>모두 끝났습니다! 이 프레임에 작업하느라 소요된 총 시간을 계산하려면 FRAME_COMPLETED - INTENDED_VSYNC를 수행하면 됩니다.
-
- </li>
- </ul>
- </li>
-
-</ul>
-
-<p>
- 이 데이터는 여러 가지 방법으로 사용할 수 있습니다. 한 가지 단순하면서도 유용한 시각화는 프레임 시간의 분배(FRAME_COMPLETED - INTENDED_VSYNC)를 여러 가지 대기 시간 버킷에서 표시한 히스토그램을 예로 들 수 있습니다. 아래 그림을 참조하십시오.
-
- 이 그래프를 보면 한 눈에 대부분의 프레임이 아주 양호했다는 것을 알아볼 수 있습니다. 대부분 16ms 최종 기한(빨간색으로 표시)보다 한참 아래에 있지만, 최종 기한을 크게 넘어선 프레임도 몇 개 있습니다.
-
- 이 히스토그램에서 시간 경과에 따른 변화를 살펴보면 대규모 이동이나 새 이상값이 생성되는 것을 확인할 수 있습니다.
- 이외에도 데이터 내의 수많은 타임스탬프를 근거로 입력 대기 시간, 레이아웃에서 보낸 시간 또는 여타 비슷한 흥미로운 메트릭도 그래프로 표현할 수 있습니다.
-
-
-</p>
-
-<img src="{@docRoot}preview/images/perf-test-framestats.png">
-
-
-<h3 id="timing-dump">단순한 프레임 타이밍 덤프</h3>
-
-<p>
- <strong>프로필 GPU 렌더링</strong>이 개발자 옵션에서 <strong>adb 셸의 dumpsys gfxinfo</strong>로 설정된 경우, <code>adb shell dumpsys gfxinfo</code> 명령이 가장 최근의 120개 프레임에 대한 타이밍 정보를 출력하되, 몇 개의 서로 다른 카테고리로 나누어 탭으로 구분된 값을 담아 표현합니다.
-
-
- 이 데이터를 사용하면 드로잉 파이프라인의 어떤 부분이 레벨이 높을 때 느려지는지 나타내는 데 유용합니다.
-
-</p>
-
-<p>
- 위의 <a href="#fs-data-format">framestats</a>와 마찬가지로, 이것을 개발자가 선택한 스프레드시트 도구에 붙여넣거나 수집해서 스크립트로 구문 분석하는 작업은 매우 단도직입적입니다.
-
- 다음 그래프는 앱이 생성한 수많은 프레임이 어디에서 시간을 보내는지 분석한 내용을 표시한 것입니다.
-
-</p>
-
-<img src="{@docRoot}preview/images/perf-test-frame-latency.png">
-
-<p>
- Gfxinfo를 실행한 결과, 그 출력을 복사하여 이를 스프레드시트 애플리케이션에 붙여넣은 다음 데이터를 누적 가로 막대형 그래프로 나타내는 것입니다.
-
-</p>
-
-<p>
- 각 세로 막대는 애니메이션 한 프레임을 나타냅니다. 그 막대의 높이가 해당 애니메이션 프레임을 계산하는 데 걸린 밀리초 수를 나타냅니다.
- 막대에서 색이 지정된 각 세그먼트는 렌더링 파이프라인의 각기 다른 단계를 나타내므로, 개발자는 이것을 보고 애플리케이션의 어떤 부분이 병목 현상을 유발하고 있는지 확인할 수 있습니다.
-
- 렌더링 파이프라인을 잘 이해하고 이에 맞게 최적화하는 법에 대한 자세한 내용은 <a href="https://www.youtube.com/watch?v=we6poP0kw6E&amp;index=27&amp;list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">무효화 레이아웃 및 성능</a> 비디오를 참조하십시오.
-
-
-</p>
-
-
-<h3 id="collection-window">상태 수집 창 제어</h3>
-
-<p>
- Framestats와 단순한 프레임 타이밍은 양쪽 모두 아주 짧은 시간 범위 동안 데이터를 수집합니다. 렌더링 약 2초에 상당하는 시간입니다.
- 이 시간 범위를 정확하게 제어하려면(예: 데이터를 특정 애니메이션에 제한), 카운터를 모두 초기화한 다음 수집한 통계를 집계하면 됩니다.
-
-
-</p>
-
-<pre>
-&gt;adb shell dumpsys gfxinfo &lt;PACKAGE_NAME&gt; reset
-</pre>
-
-<p>
- 이 방법은 명령 자체를 덤프하는 방법과 함께 써서 정기적인 간격을 두고 수집과 초기화를 반복하여 계속해서 2초 미만의 프레임 창을 캡처하도록 하는 데 쓰일 수도 있습니다.
-
-
-</p>
-
-
-<h3 id="diagnose">성능 저하 진단</h3>
-
-<p>
- 성능이 저하된 것을 알아내는 것은 문제를 추적하고 애플리케이션의 건강 상태를 높은 수준으로 유지 관리하는 데 좋은 첫 단계입니다.
- 그러나 dumpsys는 문제의 존재 여부와 상대적인 심각도만 식별하는 데 그치지 않습니다.
- 각 성능 문제의 제각기 다른 원인을 진단하고 이를 해결하기 위해 적절한 방법을 찾아야 하는 것은 변하지 않습니다.
- 이를 위해, <a href="{@docRoot}tools/help/systrace.html">systrace</a> 도구를 사용하는 것을 적극적으로 추천합니다.
-
-</p>
-
-
-<h3 id="resources">추가 리소스</h3>
-
-<p>
- Android의 렌더링 파이프라인의 작동 원리나 여기에서 마주칠 수 있는 보편적인 문제와 그 해결 방법에 대한 자세한 정보를 원하시면, 다음 리소스 중 몇 가지를 유용하게 쓸 수 있습니다.
-
-
-</p>
-
-<ul>
- <li>렌더링 성능의 기초
- </li>
- <li>왜 60fps일까요?
- </li>
- <li>Android UI와 GPU
- </li>
- <li>무효화 레이아웃 및 성능
- </li>
- <li>Systrace로 UI 성능 분석하기
- </li>
-</ul>
-
-
-<h2 id="automate">UI 성능 테스트 자동화</h2>
-
-<p>
- UI 성능 테스트에 대한 한 가지 관점은 그저 인간 테스터가 대상 앱에서 일련의 사용자 작업을 수행하도록 하는 것입니다. 그러면서 육안으로 jank가 있는지 살펴보든가, 아니면 오랜 시간을 들여 도구 중심적인 관점으로 jank를 찾아내는 것입니다.
-
- 하지만 이와 같은 수동식 방법은 위험 투성이입니다. 프레임 속도 변화를 인지하는 사람의 능력에는 개인차가 극명하고, 시간도 오래 걸릴 뿐더러 지루하고 오류가 발생할 가능성이 높습니다.
-
-
-</p>
-
-<p>
- 보다 효율적인 접근 방식은 자동화된 UI 테스트로부터 가져온 주요 성능 메트릭을 기록하고 분석하는 것입니다.
- Android M 개발자 미리 보기에는 새로운 로깅 기능이 포함되어 있어 애플리케이션 애니메이션의 jank의 양과 심각도를 판별하기 쉽고, 이를 사용해 현재 성능을 판단하고 앞으로의 성능 목표를 추적하기 위해 철저한 프로세스를 구축할 수도 있습니다.
-
-
-
-</p>
-
-<p>
- 이 글에서는 그러한 데이터를 사용하여 성능 테스트를 자동화하는 데 권장되는 방안을 찬찬히 알려드립니다.
-
-</p>
-
-<p>
- 이것은 주로 두 가지 주요 작업으로 나뉘어 있습니다. 첫째로 무엇을 테스트할지, 어떻게 테스트할지를 확인합니다. 그런 다음 두 번째로 자동화된 테스트 환경을 설정하고 유지 관리하는 것입니다.
-
-
-</p>
-
-
-<h3 id="ui-tests">UI 테스트 설정</h3>
-
-<p>
- 자동화된 테스트를 시작하기 전에 우선 몇 가지 수준 높은 결정을 내려야 합니다. 그래야 테스트 공간과 스스로에게 필요한 부분을 제대로 숙지할 수 있습니다.
-
-</p>
-
-<h4>
- 테스트할 주요 애니메이션/흐름 알아내기
-</h4>
-
-<p>
- 성능이 불량한 것이 사용자에게 가장 눈에 띄는 것은 애니메이션이 원활히 작동하지 않을 때라는 점을 명심하십시오.
- 따라서, 테스트할 UI 작업 유형을 식별할 때에는 사용자가 가장 많이 접하게 되는 애니메이션이나 사용자 환경에 가장 중요한 것에 주안점을 두면 유용합니다.
-
- 예를 들어 다음은 이처럼 식별하는 데 유용하게 쓰일 수 있는 몇 가지 보편적인 시나리오입니다.
-</p>
-
-<ul>
- <li>기본 ListView 또는 RecyclerView를 스크롤링
- </li>
-
- <li>비동기 대기 주기 동안 표시되는 애니메이션
- </li>
-
- <li>비트맵 로딩/조작이 들어 있을 수 있는 모든 애니메이션
- </li>
-
- <li>알파 혼합이 포함된 애니메이션
- </li>
-
- <li>Canvas로 사용자 지정 보기 드로잉
- </li>
-</ul>
-
-<p>
- 팀 구성원인 엔지니어, 디자이너와 제품 관리자와 협력하여 이와 같이 테스트 대상 범위에 넣어야 하는 주요 제품 애니메이션의 우선 순위를 지정하십시오.
-
-</p>
-
-<h4>
- 앞으로의 목표를 정의하고 그것을 추적하기
-</h4>
-
-<p>
- 레벨이 높을 때에는 특정한 성능 목표를 알아내고 테스트 작성에 집중하며, 그에 관한 데이터를 수집하는 것이 매우 중요할 수 있습니다.
- 예를 들면 다음과 같습니다.
-</p>
-
-<ul>
- <li>처음에만 UI 성능을 추적하여 좀 더 자세히 알아보기만 했으면 합니까?
- </li>
-
- <li>앞으로 마주치게 될 성능 저하를 방지하고자 합니까?
- </li>
-
- <li>지금은 매끄러운 프레임 비율이 약 90% 정도이지만 이번 사분기 내에 98%까지 올리고자 합니까?
- </li>
-
- <li>지금 매끄러운 프레임이 약 98%이고 성능이 저하되지 않기를 바랍니까?
- </li>
-
- <li>저사양 기기에서 성능을 개선하는 것이 목표입니까?
- </li>
-</ul>
-
-<p>
- 이 모든 경우, 애플리케이션의 여러 버전에 걸쳐 성능을 나타내주는 사용 기록 추적을 수행하는 것이 좋습니다.
-
-</p>
-
-<h4>
- 테스트할 기기 정하기
-</h4>
-
-<p>
- 애플리케이션의 성능은 어느 기기에서 실행되는지에 따라 여러 가지로 달라집니다. 메모리 용량이 적고 GPU 파워가 딸리거나 CPU 칩 속도가 느린 기기도 있습니다.
- 이는 즉 한 가지 하드웨어 세트에서는 잘 작동하는 애니메이션이 다른 곳에서는 그렇지 않을 수도 있다는 뜻입니다. 더 나쁜 경우로는 파이프라인의 서로 다른 부분에서 병목 현상이 일어나는 결과를 초래할 수도 있습니다.
-
- 따라서, 사용자가 볼 수도 있는 이러한 변형을 감안하기 위해 테스트를 실행할 기기를 여러 가지로 선택하는 것이 중요합니다. 최신 고사양 기기, 저사양 기기, 태블릿 등 양쪽 측면을 모두 고려하십시오.
-
- CPU 성능, RAM, 화면 밀도, 크기 등의 변형을 잘 살피십시오.
- 고사양 기기를 통과하는 테스트가 저사양 기기에서는 실패할 수도 있습니다.
-
-</p>
-
-<h4>
- UI 테스트의 기본 프레임워크
-</h4>
-
-<p>
- <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>와 <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso</a> 등의 도구 스위트는 개발자의 애플리케이션을 통과하는 사용자의 동작을 자동화하는 데 도움이 되도록 구축된 것입니다.
-
- 이들은 단순한 프레임워크로, 사용자와 기기의 상호작용을 흉내 냅니다.
- 이러한 프레임워크를 사용하려면, 사실상 개발자가 나름의 고유한 스크립트를 생성해야 합니다. 이는 일련의 사용자-동작을 통해 실행되고, 이를 기기 자체에서 재생합니다.
-
-
-</p>
-
-<p>
- 이렇게 자동화된 테스트를 여러 가지로 조합하여 <code>dumpsys gfxinfo</code>와 함께 사용하면 재현 가능한 시스템을 재빨리 만들어내 테스트를 실행하고 해당 조건 하에서 성능 정보를 측정할 수 있습니다.
-
-
-</p>
-
-
-<h3 id="automated-tests">자동화된 UI 테스트 설정</h3>
-
-<p>
- UI 테스트를 실행할 수 있게 되고, 한 번의 테스트로부터 데이터를 수집할 파이프라인을 갖추게 되면 다음으로 중요한 단계는 해당 테스트를 여러 번, 여러 기기에 걸쳐 실행하고 그 결과 도출된 성능 데이터를 집계하여 개발 팀이 한층 더 상세하게 분석할 수 있게 해주는 프레임워크를 채택하는 것입니다.
-
-
-
-</p>
-
-<h4>
- 테스트 자동화를 위한 프레임워크
-</h4>
-
-<p>
- UI 테스트 프레임워크(예: <a href="{@docRoot}training/testing/ui-testing/uiautomator-testing.html">UI Automator</a>)는 대상 기기/에뮬레이터에서 직접 실행된다는 점에 주목할 만한 가치가 있습니다.
- 반면 <em>dumpsys gfxinfo</em>에 의해 완료되는 성능 수집 정보는 호스트 머신이 구동하여 ADB를 통해 명령을 전송합니다.
- 이러한 각각의 항목 자동화를 연결하는 데 도움을 주기 위해 <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">MonkeyRunner</a> 프레임워크가 개발되었습니다. 이것은 호스트 머신에서 실행되는 스크립팅 시스템으로, 일련의 연결된 기기에 명령을 발행하기도 하고 이들로부터 데이터를 수신할 수도 있습니다.
-
-
-
-</p>
-
-<p>
- UI 성능 테스트를 제대로 자동화하기 위해 최소한의 수준으로 일련의 스크립트를 구축하는 경우, 다음과 같은 작업을 수행하기 위해 monkeyRunner를 활용할 수 있어야 합니다.
-
-</p>
-
-<ul>
- <li>원하는 APK를 대상 기기(하나 이상일 수 있음) 또는 에뮬레이터에 로드하여 시작합니다.
- </li>
-
- <li>UI Automator UI 테스트를 시작하고 실행되도록 허용하십시오.
- </li>
-
- <li><em>dumpsys gfxinfo</em><em></em>를 통해 성능 정보를 수집합니다.
- </li>
-
- <li>정보를 집계하고 이를 다시 유용한 방식으로 표시해 개발자에게 보여줍니다.
- </li>
-</ul>
-
-
-<h3 id="triage">관측된 문제 심사 및 수정</h3>
-
-<p>
- 문제의 패턴이나 성능 저하를 확인했으면, 다음 단계는 해결 방법을 알아내어 적용합니다.
- 자동화된 테스트 프레임워크가 프레임에 대해 정확한 타이밍 분석을 유지하는 경우, 최근의 의심스러운 코드/레이아웃 변경 내용을 꼼꼼히 훑어보거나(성능 저하의 경우) 수동 조사로 전환했을 때 시스템의 어느 부분을 분석할지 범위를 좁히는 데 도움이 될 수 있습니다.
-
-
- 수동 조사의 경우, <a href="{@docRoot}tools/help/systrace.html">systrace</a>부터 시작하는 것이 좋습니다. 이렇게 하면 렌더링 파이프라인의 모든 단계, 시스템에 있는 모든 스레드와 코어는 물론 개발자가 정의한 사용자 지정 이벤트 마커 일체에 대해 정확한 타이밍 정보를 나타내주기 때문입니다.
-
-
-</p>
-
-<h4>
- 임시 타이밍을 적절하게 프로파일링하기
-</h4>
-
-<p>
- 렌더링 성능에서 타이밍을 가져와 이를 측정하는 데 수반되는 몇 가지 어려움을 알아두는 것이 중요합니다.
- 이와 같은 숫자는 본래 결정적인 것이 아니고 시스템 상태, 이용 가능한 메모리 용량, 열 제한 및 개발자가 사는 지역에 태양 플레어가 마지막으로 영향을 미친 시점 등에 따라 변동폭이 큽니다.
-
- 요점은 같은 테스트를 두 번 실행하면서 서로 근사치이지만 완전히 똑같지는 않은, 약간 다른 숫자를 얻어내는 데 있습니다.
-
-
-</p>
-
-<p>
- 이런 식으로 데이터를 제대로 수집하고 프로파일링한다는 것은 같은 테스트를 여러 번 거듭 실행하면서 얻어지는 결과를 평균 또는 중간값(너무 복잡해지니 이것을 '배치(batch)'라고 부르기로 합시다)으로 누적한다는 것을 뜻합니다. 이렇게 하면 테스트 성과를 대략적으로 어림잡을 수 있으면서 정확한 타이밍은 없어도 됩니다.
-
-
-
-</p>
-
-<p>
- 이러한 배치를 코드 변경 사이사이에 사용하여 그러한 변경 내용이 성능에 미치는 상대적인 영향을 알아볼 수도 있습니다.
- 변경 전 배치의 평균 프레임 속도가 변경 후 배치에서보다 빠른 경우, 해당 변경에 대해 전반적으로 좋은 WRT 성능을 성취했다는 뜻입니다.
-
-
-</p>
-
-<p>
- 이는 즉 개발자가 수행하는 자동화된 UI 테스트는 모두 이 개념을 감안해야 한다는 뜻이기도 하고, 테스트 중에 일어나는 모든 변칙적인 부분 또한 감안해야 한다는 뜻입니다.
- 예를 들어 애플리케이션 성능이 일종의 기기 문제(본인의 애플리케이션에서 기인한 것이 아님) 때문에 갑자기 뚝 떨어지는 경우라면 해당 배치를 다시 실행하여 조금 덜 혼란스러운 타이밍을 얻어야 할 수도 있습니다.
-
-
-
-</p>
-
-<p>
- 그렇다면 측정값이 의의를 지니려면 테스트를 몇 번이나 수행하는 것이 좋습니까? 최소한 10번은 해야 합니다. 실행 횟수가 50이나 100처럼 커질수록 더욱 정확한 경과를 도출할 수 있습니다(물론, 이제는 정확도와 시간을 맞바꿔야 하는 셈입니다).
-
-
-</p>
diff --git a/docs/html-intl/intl/ko/sdk/index.jd b/docs/html-intl/intl/ko/sdk/index.jd
new file mode 100644
index 000000000000..d68d736fd5c8
--- /dev/null
+++ b/docs/html-intl/intl/ko/sdk/index.jd
@@ -0,0 +1,431 @@
+page.title=Android Studio 및 SDK 도구 다운로드
+page.tags=sdk, android studio
+page.template=sdk
+page.image=images/cards/android-studio_2x.png
+header.hide=1
+page.metaDescription=Android 휴대폰, 태블릿, 웨어러블, TV 등을 위한 앱을 구축하는 데 사용할 수 있는 공식 Android IDE 및 개발자 도구를 다운로드하세요.
+
+@jd:body
+
+<style type="text/css">
+ .offline {display:none;}
+ h2.feature {
+ padding-top:30px;
+ margin-top:0;
+ clear:both;
+ }
+ .feature-blurb {
+ margin:0px; font-size:16px; font-weight:300;
+ padding-top:40px;
+ }
+
+ .landing-button .small {
+ font-size: 12px;
+ font-weight: normal;
+ line-height: 12px;
+ display: block;
+ }
+
+ h1.studio-logo {
+ width:226px;
+ height:78px;
+ display:block;
+ padding:0;
+ white-space: nowrap;
+ text-indent: -10000px;
+ font-size:0px;
+ background: url({@docRoot}images/tools/studio-logo.png);
+ background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x);
+ background-size: 226px 78px;
+ }
+
+</style>
+
+
+
+
+
+<div style="position:relative;">
+
+
+<div class="wrap" id="tos" style="display:none;width:inherit;height:650px">
+<div class="col-13" style="margin:0;">&nbsp;</div><!-- provides top margin for content -->
+
+<h1 id="tos-header" style="margin-top:0">다운로드</h1>
+
+<p class="sdk-terms-intro">Android Studio 또는 독립 실행형 SDK 도구를 설치하려면,
+먼저 다음 사용 약관에 동의해야 합니다.</p>
+
+<div class="sdk-terms" onfocus="this.blur()">
+<h2 class="norule">사용 약관</h2>
+이것은 Android SDK(소프트웨어 개발 키트)에 대한 라이선스 계약입니다.
+
+
+<h3>1. Introduction</h3>
+1.1 The Android Software Development Kit (referred to in the License Agreement as the "SDK" and specifically including the Android system files, packaged APIs, and Google APIs add-ons) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the SDK.
+
+1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
+
+1.3 A "compatible implementation" means any Android device that (i) complies with the Android Compatibility Definition document, which can be found at the Android compatibility website (http://source.android.com/compatibility) and which may be updated from time to time; and (ii) successfully passes the Android Compatibility Test Suite (CTS).
+
+1.4 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+
+
+<h3>2. Accepting this License Agreement</h3>
+2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use the SDK if you do not accept the License Agreement.
+
+2.2 By clicking to accept, you hereby agree to the terms of the License Agreement.
+
+2.3 You may not use the SDK and may not accept the License Agreement if you are a person barred from receiving the SDK under the laws of the United States or other countries, including the country in which you are resident or from which you use the SDK.
+
+2.4 If you are agreeing to be bound by the License Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the SDK on behalf of your employer or other entity.
+
+
+<h3>3. SDK License from Google</h3>
+3.1 Subject to the terms of the License Agreement, Google grants you a limited, worldwide, royalty-free, non-assignable, non-exclusive, and non-sublicensable license to use the SDK solely to develop applications for compatible implementations of Android.
+
+3.2 You may not use this SDK to develop applications for other platforms (including non-compatible implementations of Android) or to develop another SDK. You are of course free to develop applications for other platforms, including non-compatible implementations of Android, provided that this SDK is not used for that purpose.
+
+3.3 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
+
+3.4 You may not use the SDK for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK.
+
+3.5 Use, reproduction and distribution of components of the SDK licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement.
+
+3.6 You agree that the form and nature of the SDK that Google provides may change without prior notice to you and that future versions of the SDK may be incompatible with applications developed on previous versions of the SDK. You agree that Google may stop (permanently or temporarily) providing the SDK (or any features within the SDK) to you or to users generally at Google's sole discretion, without prior notice to you.
+
+3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
+
+3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the SDK.
+
+
+<h3>4. Use of the SDK by You</h3>
+4.1 Google agrees that it obtains no right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the SDK, including any intellectual property rights that subsist in those applications.
+
+4.2 You agree to use the SDK and write applications only for purposes that are permitted by (a) the License Agreement and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
+
+4.3 You agree that if you use the SDK to develop applications for general public users, you will protect the privacy and legal rights of those users. If the users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If the user provides your application with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, the user has given you permission to do so.
+
+4.4 You agree that you will not engage in any activity with the SDK, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of any third party including, but not limited to, Google or any mobile communications carrier.
+
+4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
+
+4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
+
+
+<h3>5. Your Developer Credentials</h3>
+5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
+
+
+<h3>6. Privacy and Information</h3>
+6.1 In order to continually innovate and improve the SDK, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the SDK are being used and how they are being used. Before any of this information is collected, the SDK will notify you and seek your consent. If you withhold consent, the information will not be collected.
+
+6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in accordance with Google's Privacy Policy.
+
+
+<h3>7. Third Party Applications</h3>
+7.1 If you use the SDK to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
+
+7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
+
+7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party. In that case, the License Agreement does not affect your legal relationship with these third parties.
+
+
+<h3>8. Using Android APIs</h3>
+8.1 Google Data APIs
+
+8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
+
+8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
+
+
+<h3>9. Terminating this License Agreement</h3>
+9.1 The License Agreement will continue to apply until terminated by either you or Google as set out below.
+
+9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the SDK and any relevant developer credentials.
+
+9.3 Google may at any time, terminate the License Agreement with you if:
+(A) you have breached any provision of the License Agreement; or
+(B) Google is required to do so by law; or
+(C) the partner with whom Google offered certain parts of SDK (such as APIs) to you has terminated its relationship with Google or ceased to offer certain parts of the SDK to you; or
+(D) Google decides to no longer provide the SDK or certain parts of the SDK to users in the country in which you are resident or from which you use the service, or the provision of the SDK or certain SDK services to you by Google is, in Google's sole discretion, no longer commercially viable.
+
+9.4 When the License Agreement comes to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst the License Agreement has been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall continue to apply to such rights, obligations and liabilities indefinitely.
+
+
+<h3>10. DISCLAIMER OF WARRANTIES</h3>
+10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+
+10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE.
+
+10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+
+
+<h3>11. LIMITATION OF LIABILITY</h3>
+11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+
+
+<h3>12. Indemnification</h3>
+12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys fees) arising out of or accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with the License Agreement.
+
+
+<h3>13. Changes to the License Agreement</h3>
+13.1 Google may make changes to the License Agreement as it distributes new versions of the SDK. When these changes are made, Google will make a new version of the License Agreement available on the website where the SDK is made available.
+
+
+<h3>14. General Legal Terms</h3>
+14.1 The License Agreement constitutes the whole legal agreement between you and Google and governs your use of the SDK (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the SDK.
+
+14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
+
+14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.
+
+14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.
+
+14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+
+14.6 The rights granted in the License Agreement may not be assigned or transferred by either you or Google without the prior written approval of the other party. Neither you nor Google shall be permitted to delegate their responsibilities or obligations under the License Agreement without the prior written approval of the other party.
+
+14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+
+<em>November 20, 2015</em>
+</div>
+
+
+
+
+
+<div id="next-steps" style="display:none;position:absolute;width:inherit">
+ <p>이제 금방 Android용 앱 구축을 시작할 수 있게 됩니다!</p>
+ <p>곧
+<a id="next-link" href="{@docRoot}sdk/installing/index.html">Android SDK 설치하기</a> 페이지로 이동됩니다.</p>
+
+</div><!-- end next-steps -->
+
+
+
+<div id="sdk-terms-form">
+<p>
+<input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" />
+<label id="agreeLabel" for="agree">본인은 상기 사용 약관을 읽었으며 이에 동의합니다.</label>
+</p>
+<p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p>
+</div>
+
+
+</div><!-- end TOS -->
+
+
+
+
+
+
+<div id="landing">
+
+<div class="col-13">&nbsp;</div><!-- provides top margin for content -->
+
+<img src="{@docRoot}images/tools/studio-hero.png" srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x" width="760" height="400"/>
+
+<div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px">
+
+<h1 class="studio-logo" style="margin:0 0 35px !important">Android Studio</h1>
+
+<p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block;
+width: 400px;text-align: center;">공식 Android IDE</p>
+
+<ul style="font-size:12px;line-height:19px;">
+<li>Android Studio IDE</li>
+<li>Android SDK Tools</li>
+<li>Android 6.0(Marshmallow) 플랫폼</li>
+<li>Google API를 사용하는 Android 6.0 에뮬레이터 시스템 이미지</li>
+</ul>
+
+<a class="online landing-button green download-bundle-button"
+href="#Other" >Download Android Studio<br/><span class='small'></span></a>
+
+<!-- this appears when viewing the offline docs -->
+<p class="offline">
+Android Studio 또는 독립 실행형 SDK 도구를 얻으려면 <a href="http://developer.android.com/sdk/index.html">developer.android.com/sdk/</a> 페이지를 방문하십시오.
+</p>
+</div>
+
+<ul>
+ <li><a href="#Requirements">시스템 요건</a></li>
+ <li><a href="#Other">기타 다운로드 옵션</a></li>
+ <li><a href="{@docRoot}sdk/installing/migrate.html">Android Studio로 마이그레이션</a></li>
+ <li><a href="https://docs.google.com/a/google.com/forms/d/1mjsyfzv3HAnDY-_Kfj-3QJKdpuksyMFs9e73CRwmT6Q/viewform" target="_blank">설문조사 참여</a></li>
+</ul>
+
+
+
+
+
+<h2 class="feature norule" >지능형 코드 편집기</h2>
+
+<div class="col-9">
+ <img src="{@docRoot}images/tools/studio-hero-code.png" srcset="{@docRoot}images/tools/studio-hero-code_2x.png 2x, {@docRoot}images/tools/studio-hero-code.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Android Studio의 핵심에는 고급 코드 작성, 리팩터링, 코드 분석이 가능한 지능형
+코드 편집기가 있습니다.</p>
+ <p>이 강력한 코드 편집기를 사용하면 여러분이 더욱 생산적인 Android 앱 개발자가 되는 데 도움이 됩니다.</p>
+</div>
+
+
+
+
+
+<h2 class="feature norule">코드 템플릿 및 GitHub 통합</h2>
+
+<div class="col-9">
+ <img src="{@docRoot}images/tools/studio-hero-import.png" srcset="{@docRoot}images/tools/studio-hero-import_2x.png 2x, {@docRoot}images/tools/studio-hero-import.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>새 프로젝트 마법사를 통해 새로운 프로젝트를 더욱 쉽게 시작할 수 있습니다.</p>
+
+ <p>탐색 드로어 및 보기 호출기와 같은 패턴에 대한 템플릿 코드를 사용해 프로젝트를 시작하고,
+GitHub에서 Google 코드 샘플을 가져올 수도 있습니다.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">다중 화면 앱 개발</h2>
+
+<div class="col-9">
+ <img src="{@docRoot}images/tools/studio-hero-screens.png" srcset="{@docRoot}images/tools/studio-hero-screens_2x.png 2x, {@docRoot}images/tools/studio-hero-screens.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Android 휴대폰, 태블릿, Android Wear, Android TV,
+Android Auto 그리고 Google Glass용 앱을 구축할 수 있습니다.</p>
+ <p>Android Studio의 새로운 Android 프로젝트 보기 및 모듈 지원 기능을 통해
+앱 프로젝트 및 리소스 관리를 더욱 쉽게 수행할 수 있습니다.
+</div>
+
+
+
+
+<h2 class="feature norule">모든 모양 및 크기를 지원하는 가상 기기</h2>
+
+<div class="col-9">
+ <img src="{@docRoot}images/tools/studio-hero-avds.png" srcset="{@docRoot}images/tools/studio-hero-avds_2x.png 2x, {@docRoot}images/tools/studio-hero-avds.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Android Studio는 최적화된 에뮬레이터 이미지로 사전 구성된 형태로 제공됩니다.</p>
+ <p>업데이트되고 간소화된 Virtual Device Manager는 일반 Android 기기에 대해
+사전 정의된 기기 프로필을 제공합니다.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">
+Gradle을 통해 진화된 Android 빌드</h2>
+
+<div class="col-9">
+ <img src="{@docRoot}images/tools/studio-hero-gradle.png" srcset="{@docRoot}images/tools/studio-hero-gradle_2x.png 2x, {@docRoot}images/tools/studio-hero-gradle.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>동일한 프로젝트를 사용하여 다양한 기능을 갖춘 Android 앱을 위한 여러 APK를 생성할 수 있습니다.</p>
+ <p>Maven을 통해 앱 종속관계를 관리할 수 있습니다.</p>
+ <p>Android Studio 또는 명령줄에서 APK를 구축할 수 있습니다.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">Android Studio에 대한 추가 정보</h2>
+<div style="background:#424242;padding:30px; color:#fff;margin:0 0 15px;">
+
+<a class="online landing-button green download-bundle-button" style="margin:0 0 40px 60px;float:right" href="">Download</a>
+
+ <ul>
+ <li>JetBrains에서 제공하는 인기 있는 Java IDE인 IntelliJ IDEA Community Edition 기반</li>
+ <li>유연한 Gradle 기반 빌드 시스템</li>
+ <li>빌드 변형 및 여러 APK 생성</li>
+ <li>템플릿 지원 확대를 통해 Google Services 및 다양한 기기 유형 지원</li>
+ <li>테마 편집을 지원하는 고급 레이아웃 편집기</li>
+ <li>성능, 유용성, 버전 호환성 및 기타 문제를 파악하는 Lint 도구</li>
+ <li>ProGuard 및 앱 서명 기능</li>
+ <li>Google Cloud Messaging 및 App Engine의 통합을 용이하게 하는 Google Cloud Platform에 대한
+기본 지원 기능</li>
+ </ul>
+
+<p style="margin:0">
+Android Studio에서 사용할 수 있는 기능에 대한 자세한 내용은
+<a href="{@docRoot}tools/studio/index.html">Android Studio 개요</a> 가이드를 참조하세요.</p>
+</div>
+
+
+<p>ADT와 함께 Eclipse를 사용하고 있었다면 현재 Android의 공식 IDE는
+Android Studio이므로, 모든 최신 IDE 업데이트를 받을 수 있도록 Android Studio로
+마이그레이션해야 합니다. 프로젝트 이동에 대한 도움말은
+<a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android
+Studio</a>를 참조하세요.</p>
+
+
+
+
+
+
+
+<h2 id="Requirements">시스템 요건</h2>
+
+<h3>Windows</h3>
+
+<ul>
+<li>Microsoft&reg; Windows&reg; 8/7/Vista/2003(32비트 또는 64비트)</li>
+<li>최소 2GB RAM, 4GB RAM 권장</li>
+<li>400MB 하드 디스크 공간</li>
+<li>Android SDK, 에뮬레이터 시스템 이미지 및 캐시용 최소 1GB</li>
+<li>1280 x 800 이상의 화면 해상도</li>
+<li>JDK(Java Development Kit) 7 </li>
+<li>가속 에뮬레이터를 위한 선택 사항: Intel® VT-x, Intel® EM64T(Intel® 64) 및 XD(Execute Disable) Bit
+기능 지원 Intel® 프로세서</li>
+</ul>
+
+
+<h3>Mac OS X</h3>
+
+<ul>
+<li>Mac&reg; OS X&reg; 10.8.5 이상, 최대 10.9(Mavericks)</li>
+<li>최소 2GB RAM, 4GB RAM 권장</li>
+<li>400MB 하드 디스크 공간</li>
+<li>Android SDK, 에뮬레이터 시스템 이미지 및 캐시용 최소 1GB</li>
+<li>1280 x 800 이상의 화면 해상도</li>
+<li>JRE(Java Runtime Environment) 6</li>
+<li>JDK(Java Development Kit) 7</li>
+<li>가속 에뮬레이터를 위한 선택 사항: Intel® VT-x, Intel® EM64T(Intel® 64) 및 XD(Execute Disable) Bit
+기능 지원 Intel® 프로세서</li>
+</ul>
+
+<p>Mac OS에서는 최적화된 글꼴 렌더링을 위해 JRE(Java Runtime Environment) 6에서 Android Studio를
+실행하십시오. 그런 다음, JDK(Java Development Kit) 6 또는 JDK 7을 사용하여 프로젝트를 구성할 수 있습니다.</p>
+
+
+
+<h3>Linux</h3>
+
+<ul>
+<li>GNOME 또는 KDE 데스크톱</li>
+<li>GNU C Library(glibc) 2.15 이상</li>
+<li>최소 2GB RAM, 4GB RAM 권장</li>
+<li>400MB 하드 디스크 공간</li>
+<li>Android SDK, 에뮬레이터 시스템 이미지 및 캐시용 최소 1GB</li>
+<li>1280 x 800 이상의 화면 해상도</li>
+<li>Oracle&reg; JDK(Java Development Kit) 7 </li>
+</ul>
+<p>Ubuntu&reg; 14.04, Precise Pangolin(32비트 애플리케이션 실행 가능 64비트 버전)에서
+테스트됨</p>
+
+
+
+
+<h2 id="Other" style="clear:left">기타 다운로드 옵션</h2>
+
+<!-- alternative SDK options follows -->
diff --git a/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd b/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd
new file mode 100644
index 000000000000..b935d87afee9
--- /dev/null
+++ b/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd
@@ -0,0 +1,226 @@
+page.title=SDK 패키지 추가하기
+
+page.tags=sdk manager
+
+@jd:body
+
+<style>
+ol.large {
+ margin-left:0;
+}
+ol.large > li {
+ list-style-position: inside;
+ list-style-type:none;
+ margin:30px 0 0 0;
+ padding:30px 20px;
+ background:#eee;
+}
+ol.large > li:nth-child(odd) {
+}
+ol.large > li:before {
+ display:inline;
+ left:-40px;
+ float:left;
+ width:20px;
+ font-size:20px;
+ line-height:20px;
+}
+ol.large > li > h2 {
+ font-size:20px;
+ line-height:20px;
+ padding:0 0 0 20px;
+ margin:0 0 20px 0;
+ display:inline;
+ font-weight:normal;
+}
+ol.large > li:nth-child(1):before {
+ content:"1. ";
+}
+ol.large > li:nth-child(2):before {
+ content:"2. ";
+}
+ol.large > li:nth-child(3):before {
+ content:"3. ";
+}
+ol.large > li:nth-child(4):before {
+ content:"4. ";
+}
+ol.large > li:nth-child(5):before {
+ content:"5. ";
+}
+ol.large > li:nth-child(6):before {
+ content:"6. ";
+}
+</style>
+
+
+<p>
+기본적으로 Android SDK에는 개발을 시작하는 데 필요한 모든 것이 포함되어 있지 않습니다.
+SDK는 도구, 플랫폼과 기타 구성요소를 여러 개의
+패키지로 구분하여 필요에 따라
+<a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>를 사용하여 다운로드할 수 있습니다.
+따라서 시작하기 전에 Android SDK에 추가해야 하는 패키지가 몇 개 있습니다.</p>
+
+<p>패키지를 추가하려면, 다음 중 한 가지 방법을 사용하여 Android SDK Manager를 시작합니다.</p>
+<ul>
+ <li>Android Studio의 도구 모음에서 <strong>SDK Manager</strong>
+<img src="{@docRoot}images/tools/sdk-manager-studio.png" style="vertical-align:bottom;margin:0;height:17px" />를 클릭합니다.</li>
+ <li>Android Studio를 사용하지 않는 경우:
+ <ul>
+ <li>Windows: Android
+ SDK 디렉터리의 루트에 있는 <code>SDK Manager.exe</code> 파일을 더블 클릭합니다.</li>
+ <li>Mac/Linux: 터미널을 열고 Android SDK가 설치된 <code>tools/</code> 디렉터리로
+이동한 후 <code>android sdk</code>를 실행합니다.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>SDK Manager를 처음 열 때에는, 여러 개의 패키지가 기본적으로 선택되어
+있습니다. 이들은 선택된 상태로 두십시오. 다만 다음 단계를 따라 시작하는 데 필요한 모든 것을
+갖추고 있는지 확인해야 합니다.</p>
+
+
+<ol class="large">
+<li>
+ <h2 id="GetTools" class="norule">최신 SDK 도구 다운로드</h2>
+
+<img src="/images/sdk_manager_packages.png" alt="" width="350" style="float:right;margin-left:20px" />
+
+ <p>Android SDK를 설정할 때는
+최신 도구와 Android 플랫폼 다운로드가 최소한의 준비 사항입니다.</p>
+ <ol>
+ <li>도구 디렉터리를 열고 다음을 선택합니다.
+ <ul>
+ <li><strong>Android SDK Tools</strong></li>
+ <li><strong>Android SDK Platform-tools</strong></li>
+ <li><strong>Android SDK Build-tools</strong>(최상위 버전)</li>
+ </ul>
+ </li>
+ <li>첫 번째 Android X.X 폴더(최신 버전)를 열고 다음을 선택합니다.
+ <ul>
+ <li><strong>SDK Platform</strong></li>
+ <li>에뮬레이터용 시스템 이미지(다음 예시 참조) <br>
+ <strong>ARM EABI v7a 시스템 이미지</strong></li>
+ </ul>
+ </li>
+ </ol>
+</li>
+
+<li>
+ <h2 id="GetSupportLib" class="norule">추가 API를 위한 지원 라이브러리 가져오기</h2>
+
+ <div class="sidebox">
+ <p>지원 라이브러리는 다음 용도에 필요합니다.</p>
+ <ul>
+ <li><a href="{@docRoot}wear/index.html">Android Wear</a></li>
+ <li><a href="{@docRoot}tv/index.html">Android TV</a></li>
+ <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li>
+ </ul>
+
+ <p>또한 다음과 같은 인기 API를 제공하기도 합니다.</p>
+ <ul>
+ <li><a href="{@docRoot}reference/android/support/v4/widget/DrawerLayout.html">탐색
+창</a></li>
+ <li><a href="{@docRoot}reference/android/support/v4/view/ViewPager.html">보기 스와이프</a></li>
+ <li><a href="{@docRoot}reference/android/support/v7/app/ActionBar.html">이전 버전 호환
+동작 막대</a></li>
+ </ul>
+ </div>
+
+ <p><a href="{@docRoot}tools/support-library/features.html">Android 지원 라이브러리</a>는
+ 대부분의 Android 버전과 호환되는 광범위한 집합의 API를 제공합니다.</p>
+
+ <p><strong>Extras</strong> 디렉터리를 열고 다음을 선택합니다.</p>
+ <ul>
+ <li><strong>Android 지원 리포지토리</strong></li>
+ <li><strong>Android 지원 라이브러리</strong></li>
+ </ul>
+
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+
+</li>
+
+
+<li>
+ <h2 id="GetGoogle" class="norule">더 많은 API를 위해 Google Play 서비스 가져오기</h2>
+
+ <div class="sidebox">
+
+ <p>Google Play 서비스 API는 Android
+ 앱에 다음과 같이 다양한 기능과 서비스를 제공합니다.</p>
+ <ul>
+ <li><a href="{@docRoot}google/play-services/plus.html">사용자 인증</a></li>
+ <li><a href="{@docRoot}google/play-services/maps.html">Google Maps</a></li>
+ <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li>
+ <li><a href="{@docRoot}google/play-services/games.html">게임 도전 과제 및
+ 리더보드</a></li>
+ <li><a href="{@docRoot}google/play-services/index.html">그 외 다수</a></li>
+ </ul>
+ </div>
+
+ <p>Google API로 개발하려면 Google Play 서비스 패키지가 필요합니다.</p>
+ <p><strong>Extras</strong> 디렉터리를 열고 다음을 선택합니다.</p>
+ <ul>
+ <li><strong>Google Repository</strong></li>
+ <li><strong>Google Play 서비스</strong></li>
+ </ul>
+
+ <p class="note"><strong>참고:</strong> Google Play 서비스를 모든 Android 구동 기기에서
+사용할 수 있는 것은 아니지만, Google Play Store가 있는 기기에서는 모두 사용할 수 있습니다. 이와 같은 API를
+Android 에뮬레이터에서 사용하려면, SDK Manager의 최신 Android X.X 디렉터리에서 <strong>Google API</strong>
+ 시스템 이미지도 설치해야 합니다.</p>
+</li>
+
+
+<li>
+ <h2 id="Install" class="norule">패키지 설치</h2>
+ <p>원하는 패키지를 모두 선택하면 계속 진행하여 설치합니다.</p>
+ <ol>
+ <li><strong>X 패키지 설치</strong>를 클릭합니다.</li>
+ <li>다음 창에서, 왼쪽에 있는 각 패키지 이름을 더블 클릭하여 각각의
+라이선스 동의서를 수락합니다.</li>
+ <li><strong>설치</strong>를 클릭합니다.</li>
+ </ol>
+ <p>다운로드 진행률이 SDK Manager 창 맨 아래에 표시됩니다.
+ <strong>SDK Manager를 종료하지 마십시오</strong>. 다운로드가 취소됩니다.</p>
+</li>
+
+<li>
+ <h2 id="Build" class="norule">뭐든 구축하세요!</h2>
+
+<p>이제 Android SDK에 위의 패키지를 설치했으니 Android용 앱을 구축할 준비가 끝난
+셈입니다. 새로운 도구와 다른 API를 사용할 수 있게 되면, SDK Manager를 시작하여
+사용자의 SDK에 새 패키지를 다운로드할 수 있습니다.</p>
+
+<p>진행 방법에 대한 몇 가지 옵션을 소개합니다.</p>
+
+<div class="cols" style="padding:10px 0">
+<div class="col-4">
+<h3>시작하기</h3>
+<p>Android 개발이 처음인 경우, Android 앱의 기초를 배울 수 있는
+<strong><a href="{@docRoot}training/basics/firstapp/index.html">첫 앱 구축하기</a></strong> 가이드를 참조하십시오.</p>
+
+</div>
+<div class="col-4 box">
+<h3>웨어러블용 앱 구축하기</h3>
+<p>Android 웨어러블용 앱을 구축할 준비가 되었다면
+<strong><a href="{@docRoot}wear/preview/start.html">Android Wear용 앱 구축하기</a></strong> 가이드를 참조하십시오.</p>
+
+</div>
+<div class="col-4 box">
+<h3>Google API 사용</h3>
+<p>Maps 또는 Play Game 서비스와 같은
+Google API를 사용하려면
+<strong><a href="{@docRoot}google/play-services/setup.html">Google Play
+서비스 설정하기</a></strong> 가이드를 참조하십시오.</p>
+
+</div>
+</div><!-- end cols -->
+
+
+</li>
+
+</ol>
+
+
diff --git a/docs/html-intl/intl/ko/training/material/animations.jd b/docs/html-intl/intl/ko/training/material/animations.jd
new file mode 100644
index 000000000000..e8c6267aff10
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/animations.jd
@@ -0,0 +1,550 @@
+page.title=사용자지정 애니메이션의 정의
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#Touch">사용자지정 터치 피드백</a></li>
+ <li><a href="#Reveal">표시 효과 사용</a></li>
+ <li><a href="#Transitions">사용자지정 액티비티 전환</a></li>
+ <li><a href="#ViewState">뷰 상태 변경 애니메이트</a></li>
+ <li><a href="#AnimVector">벡터 드로어블 애니메이트</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>머티리얼 디자인에서 애니메이션은 사용자에게 자신의 동작에 대한 피드백을 제공하고, 앱과 상호작용할 때 시각적 연속성을 제공합니다.
+ 머티리얼 테마는 버튼 및 액티비티 전환을 위한 몇 가지 기본 애니메이션을 제공합니다. Android 5.0(API 레벨 21) 이상에서는 이러한 애니메이션을 사용자가 지정하거나 새로운 애니메이션을 만들 수 있습니다.
+
+</p>
+
+<ul>
+<li>터치 피드백</li>
+<li>회전하며 나타나기</li>
+<li>액티비티 전환</li>
+<li>커브 모션</li>
+<li>뷰 상태 변경</li>
+</ul>
+
+
+<h2 id="Touch">사용자지정 터치 피드백</h2>
+
+<p>머티리얼 디자인의 터치 피드백은 사용자가 UI 요소와 상호작용하는 시점에서 즉시 시각적으로 확인할 수 있습니다.
+ 버튼의 기본 터치 피드백 애니메이션은 물결 효과를 통해 서로 다른 상태 간에 전환하는 새 {@link android.graphics.drawable.RippleDrawable} 클래스를 사용합니다.
+
+</p>
+
+<p>대부분의 경우, 다음과 같이 뷰 배경을 지정하는 방식으로 뷰 XML에서 이 기능을 적용해야 합니다.
+</p>
+
+<ul>
+<li>제한된 물결의 경우, <code>?android:attr/selectableItemBackground</code></li>
+<li>뷰를 넘어 확장되는 물결의 경우, <code>?android:attr/selectableItemBackgroundBorderless</code>
+ 이 경우 물결이 null이 아닌 배경을 가진 뷰의 가장 가까운 상위 요소 위에 그려지고 해당 상위 요소까지로 제한됩니다.
+</li>
+</ul>
+
+<p class="note"><strong>참고:</strong> <code>selectableItemBackgroundBorderless</code>는 API 레벨 21에서 새로 도입된 특성입니다.
+</p>
+
+
+<p>또는 <code>ripple</code> 요소를 사용하여 {@link android.graphics.drawable.RippleDrawable}
+을 XML 리소스로 정의할 수 있습니다.</p>
+
+<p>{@link android.graphics.drawable.RippleDrawable} 객체에 색상을 지정할 수 있습니다. 기본 터치 피드백 색상을 변경하려면 테마의 <code>android:colorControlHighlight</code>
+특성을 사용합니다.
+</p>
+
+<p>자세한 내용은 {@link
+android.graphics.drawable.RippleDrawable} 클래스의 API 레퍼런스를 참조하세요.</p>
+
+
+<h2 id="Reveal">표시 효과 사용</h2>
+
+<p>표시 애니메이션은 UI 요소 그룹을 표시하거나 숨길 때 사용자에게 시각적 연속성을 제공합니다.
+ {@link android.view.ViewAnimationUtils#createCircularReveal
+ViewAnimationUtils.createCircularReveal()} 메서드를 사용하면 클리핑 서클을 애니메이트하여 뷰를 표시하거나 숨길 수 있습니다.
+</p>
+
+<p>이 효과를 사용하여 이전에 보이지 않았던 뷰를 표시하려면:</p>
+
+<pre>
+// previously invisible view
+View myView = findViewById(R.id.my_view);
+
+// get the center for the clipping circle
+int cx = (myView.getLeft() + myView.getRight()) / 2;
+int cy = (myView.getTop() + myView.getBottom()) / 2;
+
+// get the final radius for the clipping circle
+int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
+
+// create the animator for this view (the start radius is zero)
+Animator anim =
+ ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
+
+// make the view visible and start the animation
+myView.setVisibility(View.VISIBLE);
+anim.start();
+</pre>
+
+<p>이 효과를 사용하여 이전에 보였던 뷰를 숨기려면:</p>
+
+<pre>
+// previously visible view
+final View myView = findViewById(R.id.my_view);
+
+// get the center for the clipping circle
+int cx = (myView.getLeft() + myView.getRight()) / 2;
+int cy = (myView.getTop() + myView.getBottom()) / 2;
+
+// get the initial radius for the clipping circle
+int initialRadius = myView.getWidth();
+
+// create the animation (the final radius is zero)
+Animator anim =
+ ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
+
+// make the view invisible when the animation is done
+anim.addListener(new AnimatorListenerAdapter() {
+ &#64;Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ myView.setVisibility(View.INVISIBLE);
+ }
+});
+
+// start the animation
+anim.start();
+</pre>
+
+
+<h2 id="Transitions">사용자지정 액티비티 전환</h2>
+
+<!-- shared transition video -->
+<div style="width:290px;margin-left:35px;float:right">
+ <div class="framed-nexus5-port-span-5">
+ <video class="play-on-hover" autoplay="">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.mp4">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.webm">
+ <source src="{@docRoot}design/material/videos/ContactsAnim.ogv">
+ </video>
+ </div>
+ <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
+ <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>그림 1</strong> -
+ 공유 요소를 이용한 전환.</p>
+ <em>영화를 재생하려면 기기 화면을 클릭하세요.</em>
+ </div>
+</div>
+
+<p>머티리얼 디자인 앱의 액티비티 전환은 공통 요소 간의 모션 및 변환을 통해 서로 다른 상태 간에 시각적 연결을 제공합니다.
+ 들어가기 및 나가기 전환과 액티비티 간 공유 요소의 전환을 위한 사용자지정 애니메이션을 지정할 수 있습니다.
+</p>
+
+<ul>
+<li><strong>들어가기</strong> 전환은 액티비티에서 뷰가 장면 속으로 들어가는 방식을 결정합니다. 예를 들어, <em>explode</em> 들어가기 전환의 경우, 뷰가 밖에서 장면 속으로 들어가며 화면의 중앙으로 향합니다.
+
+</li>
+
+<li><strong>나가기</strong> 전환은 액티비티의 뷰가 장면을 나가는 방식을 결정합니다. 예를 들어, 나가기 전환으로 <em>explode</em>를 지정하면 뷰가 중앙에서부터 화면을 벗어납니다.
+
+</li>
+
+<li><strong>공유 요소</strong> 전환은 두 액티비티 간에 공유되는 뷰가 이 두 액티비티 간에 전환되는 방식을 결정합니다.
+ 예를 들어 두 액티비티에서 사용하는 동일한 이미지가 다른 위치에 있고 크기도 다를 경우, <em>changeImageTransform</em> 공유 요소 전환은 두 액티비티 간에 이미지를 매끄럽게 변환하고 배율을 조정합니다.
+
+</li>
+</ul>
+
+<p>Android 5.0(API 레벨 21)은 다음 들어가기 및 나가기 전환을 지원합니다.</p>
+
+<ul>
+<li><em>explode</em> - 뷰를 장면의 중앙에서 안이나 밖으로 이동합니다.</li>
+<li><em>slide</em> - 뷰를 장면의 가장자리 중 하나에서 안이나 밖으로 이동합니다.</li>
+<li><em>fade</em> - 불투명도를 변경하여 뷰를 추가하거나 장면에서 제거합니다.</li>
+</ul>
+
+<p>{@link android.transition.Visibility} 클래스를 확장하는 모든 전환은 들어가기 또는 나가기 전환으로 지원됩니다.
+ 자세한 내용은
+{@link android.transition.Transition} 클래스의 API 레퍼런스를 참조하세요.</p>
+
+<p>Android 5.0(API 레벨 21)은 다음의 공유 요소 전환도 지원합니다.</p>
+
+<ul>
+<li><em>changeBounds</em> - 대상 뷰의 레이아웃 경계에서 변경을 애니메이트합니다.</li>
+<li><em>changeClipBounds</em> - 대상 뷰의 클리핑 경계에서 변경을 애니메이트합니다.</li>
+<li><em>changeTransform</em> - 대상 뷰의 배율 및 회전 변경을 애니메이트합니다.</li>
+<li><em>changeImageTransform</em> - 대상 이미지의 크기 및 배율 변경을 애니메이트합니다.</li>
+</ul>
+
+<p>앱에서 액티비티 전환을 활성화할 경우, 들어가기 및 나가기 액티비티 간에 기본 크로스페이딩(cross-fading) 전환이 활성화됩니다.
+</p>
+
+<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405" style="margin-top:20px" />
+<p class="img-caption">
+  <strong>그림 2</strong> - 하나의 공유 요소로 장면 전환.
+</p>
+
+<h3>사용자지정 전환 지정</h3>
+
+<p>먼저 머티리얼 테마에서 상속하는 스타일을 정의할 때, <code>android:windowContentTransitions</code>
+특성을 통해 창 콘텐츠 전환을 활성화합니다. 들어가기, 나가기 및 공유 요소 전환도 스타일 정의에서 지정할 수 있습니다.
+</p>
+
+<pre>
+&lt;style name="BaseAppTheme" parent="android:Theme.Material">
+ &lt;!-- enable window content transitions -->
+ &lt;item name="android:windowContentTransitions">true&lt;/item>
+
+ &lt;!-- specify enter and exit transitions -->
+ &lt;item name="android:windowEnterTransition">@transition/explode&lt;/item>
+ &lt;item name="android:windowExitTransition">@transition/explode&lt;/item>
+
+ &lt;!-- specify shared element transitions -->
+ &lt;item name="android:windowSharedElementEnterTransition">
+ &#64;transition/change_image_transform&lt;/item>
+ &lt;item name="android:windowSharedElementExitTransition">
+ &#64;transition/change_image_transform&lt;/item>
+&lt;/style>
+</pre>
+
+<p>이 예에서 <code>change_image_transform</code> 전환은 다음과 같이 정의됩니다.</p>
+
+<pre>
+&lt;!-- res/transition/change_image_transform.xml -->
+&lt;!-- (see also Shared Transitions below) -->
+&lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;changeImageTransform/>
+&lt;/transitionSet>
+</pre>
+
+<p><code>changeImageTransform</code> 요소는
+{@link android.transition.ChangeImageTransform} 클래스에 해당합니다. 자세한 내용은 {@link android.transition.Transition}의 API 레퍼런스를 참조하세요.
+</p>
+
+<p>코드에서 창 콘텐츠 전환을 활성화하려면
+{@link android.view.Window#requestFeature Window.requestFeature()} 메서드를 호출합니다.</p>
+
+<pre>
+// inside your activity (if you did not enable transitions in your theme)
+getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+
+// set an exit transition
+getWindow().setExitTransition(new Explode());
+</pre>
+
+<p>코드에서 전환을 지정하려면 {@link
+android.transition.Transition} 객체를 사용하여 다음과 같은 메서드를 호출합니다.</p>
+
+<ul>
+ <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li>
+ <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li>
+ <li>{@link android.view.Window#setSharedElementEnterTransition
+ Window.setSharedElementEnterTransition()}</li>
+ <li>{@link android.view.Window#setSharedElementExitTransition
+ Window.setSharedElementExitTransition()}</li>
+</ul>
+
+<p>{@link android.view.Window#setExitTransition setExitTransition()} 및 {@link
+android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} 메서드는 호출하는 액티비티의 나가기 전환을 정의합니다.
+ {@link android.view.Window#setEnterTransition
+setEnterTransition()} 및 {@link android.view.Window#setSharedElementEnterTransition
+setSharedElementEnterTransition()} 메서드는 호출되는 액티비티의 들어가기 전환을 정의합니다.</p>
+
+<p>전환 효과를 극대화하려면 호출하는 액티비티와 호출되는 액티비티 모두에서 창 콘텐츠 전환을 활성화해야 합니다.
+ 그렇지 않으면 호출하는 액티비티가 나가기 전환을 시작하지만, 배율 또는 페이드와 같은 창 전환이 나타납니다.
+</p>
+
+<p>들어가기 전환을 최대한 빨리 시작하려면 호출되는 액티비티에서
+{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()}
+ 메서드를 사용하세요. 그러면 더욱 인상적인 들어가기 전환이 가능합니다.</p>
+
+<h3>전환을 사용하여 액티비티 시작</h3>
+
+<p>전환을 활성화하고 액티비티에 대해 나가기 전환을 설정한 경우, 다음과 같이 다른 액티비티를 시작하면 전환이 활성화됩니다.
+</p>
+
+<pre>
+startActivity(intent,
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
+</pre>
+
+<p>두 번째 액티비티에 대해 들어가기 전환을 설정한 경우, 액티비티가 시작되면 전환도 활성화됩니다.
+ 다른 액티비티를 시작할 때 전환을 비활성화하려면 <code>null</code> 옵션 번들을 제공하십시오.
+</p>
+
+<h3>공유 요소를 가진 액티비티 시작</h3>
+
+<p>공유 요소를 가진 두 액티비티 간에 화면 전환 애니메이션을 만들려면:</p>
+
+<ol>
+<li>테마에서 창 콘텐츠 전환을 활성화합니다.</li>
+<li>스타일에서 공유 요소 전환을 지정합니다.</li>
+<li>전환을 XML 리소스로 정의합니다.</li>
+<li>
+ <code>android:transitionName</code> 특성을 사용하여 두 레이아웃의 공유 요소에 공통 이름을 지정합니다.</li>
+<li>{@link android.app.ActivityOptions#makeSceneTransitionAnimation
+ActivityOptions.makeSceneTransitionAnimation()} 메서드를 사용합니다.</li>
+</ol>
+
+<pre>
+// get the element that receives the click event
+final View imgContainerView = findViewById(R.id.img_container);
+
+// get the common element for the transition in this activity
+final View androidRobotView = findViewById(R.id.image_small);
+
+// define a click listener
+imgContainerView.setOnClickListener(new View.OnClickListener() {
+ &#64;Override
+ public void onClick(View view) {
+ Intent intent = new Intent(this, Activity2.class);
+ // create the transition animation - the images in the layouts
+ // of both activities are defined with android:transitionName="robot"
+ ActivityOptions options = ActivityOptions
+ .makeSceneTransitionAnimation(this, androidRobotView, "robot");
+ // start the new activity
+ startActivity(intent, options.toBundle());
+ }
+});
+</pre>
+
+<p>코드에서 생성하는 공유된 동적 뷰의 경우,
+{@link android.view.View#setTransitionName View.setTransitionName()} 메서드를 사용하여 두 액티비티의 공통 요소 이름을 지정합니다.
+</p>
+
+<p>두 번째 액티비티 종료 시, 장면 전환 애니메이션을 되돌리려면 {@link android.app.Activity#finish Activity.finish()} 대신
+{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()}
+ 메서드를 호출합니다.</p>
+
+<h3>여러 공유 요소를 가진 액티비티 시작</h3>
+
+<p>2개 이상의 공유 요소를 가진 두 액티비티 간에 적용할 장면 전환 애니메이션을 만들려면 <code>android:transitionName</code>
+특성으로 (또는 두 액티비티에서{@link android.view.View#setTransitionName View.setTransitionName()} 메서드를 사용하여) 두 레이아웃의 공유 요소를 정의하고 다음과 같이 {@link android.app.ActivityOptions} 개체를 생성합니다.
+
+</p>
+
+<pre>
+ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
+ Pair.create(view1, "agreedName1"),
+ Pair.create(view2, "agreedName2"));
+</pre>
+
+
+<h2 id="CurvedMotion">커브 모션 사용</h2>
+
+<p>머티리얼 디자인의 애니메이션은 시간 보간 및 공간 이동 패턴에서 커브를 사용합니다.
+ Android 5.0(API 레벨 21) 이상에서 애니메이션의 사용자지정 타이밍 커브 및 커브 모션 패턴을 정의할 수 있습니다.
+</p>
+
+<p>{@link android.view.animation.PathInterpolator} 클래스는 베지어 곡선 또는 {@link android.graphics.Path} 개체를 기반으로 하는 새 보간기입니다.
+ 이 보간기는 생성자 인수를 사용하여 지정된 기준점 (0,0) 및 (1,1)과 제어점으로 모션 커브를 1x1 정사각형 안에 지정합니다.
+
+ 또한 경로 보간기를 XML 리소스로 정의할 수도 있습니다.</p>
+
+<pre>
+&lt;pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:controlX1="0.4"
+ android:controlY1="0"
+ android:controlX2="1"
+ android:controlY2="1"/>
+</pre>
+
+<p>시스템은 머티리얼 디자인 사양에서 세 가지 기본 커브에 대한 XML 리소스를 제공합니다.
+</p>
+
+<ul>
+ <li><code>&#64;interpolator/fast_out_linear_in.xml</code></li>
+ <li><code>&#64;interpolator/fast_out_slow_in.xml</code></li>
+ <li><code>&#64;interpolator/linear_out_slow_in.xml</code></li>
+</ul>
+
+<p>{@link android.view.animation.PathInterpolator} 객체를 {@link
+android.animation.Animator#setInterpolator Animator.setInterpolator()} 메서드에 전달할 수 있습니다.</p>
+
+<p>{@link android.animation.ObjectAnimator} 클래스에는 한 번에 2개 이상의 속성을 사용하여 경로를 따라 좌표를 애니메이트할 수 있는 새 생성자가 있습니다.
+ 예를 들어 다음 애니메이터는 뷰의 X 및 Y 속성을 애니메이트하기 위해 {@link android.graphics.Path} 객체를 사용합니다.
+</p>
+
+<pre>
+ObjectAnimator mAnimator;
+mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
+...
+mAnimator.start();
+</pre>
+
+
+<h2 id="ViewState">뷰 상태 변경 애니메이트</h2>
+
+<p>{@link android.animation.StateListAnimator} 클래스를 사용하면 뷰의 상태가 변경될 때 실행되는 애니메이터를 정의할 수 있습니다.
+ 다음 예는 {@link
+android.animation.StateListAnimator}를 XML 리소스로 정의하는 방법을 보여줍니다.</p>
+
+<pre>
+&lt;!-- animate the translationZ property of a view when pressed -->
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;item android:state_pressed="true">
+ &lt;set>
+ &lt;objectAnimator android:propertyName="translationZ"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:valueTo="2dp"
+ android:valueType="floatType"/>
+ &lt;!-- you could have other objectAnimator elements
+ here for "x" and "y", or other properties -->
+ &lt;/set>
+ &lt;/item>
+ &lt;item android:state_enabled="true"
+ android:state_pressed="false"
+ android:state_focused="true">
+ &lt;set>
+ &lt;objectAnimator android:propertyName="translationZ"
+ android:duration="100"
+ android:valueTo="0"
+ android:valueType="floatType"/>
+ &lt;/set>
+ &lt;/item>
+&lt;/selector>
+</pre>
+
+<p>사용자지정 뷰 상태 애니메이션을 뷰에 첨부하려면 이 예와 같이 XML 리소스 파일의
+<code>selector</code> 요소를 사용하여 애니메이터를 정의한 후에 <code>android:stateListAnimator</code> 특성을 통해 뷰에 할당합니다.
+ 코드에서 뷰에 상태 목록 애니메이터를 할당하려면 {@link android.animation.AnimatorInflater#loadStateListAnimator
+AnimationInflater.loadStateListAnimator()} 메서드를 사용하고,
+{@link android.view.View#setStateListAnimator View.setStateListAnimator()} 메서드로 애니메이터를 뷰에 할당합니다.
+</p>
+
+<p>머티리얼 테마를 확장하는 테마의 경우, 버튼은 기본적으로 Z 애니메이션을 가집니다. 버튼에서 이러한 동작을 피하려면 <code>android:stateListAnimator</code> 특성을
+<code>@null</code>로 설정합니다.
+</p>
+
+<p>{@link android.graphics.drawable.AnimatedStateListDrawable} 클래스를 사용하면 연관된 뷰의 상태 변경 사이에 애니메이션을 보여주는 Drawable을 생성할 수 있습니다.
+ Android 5.0의 일부 시스템 위젯은 이러한 애니메이션을 기본적으로 사용합니다.
+ 다음 예는 {@link android.graphics.drawable.AnimatedStateListDrawable}를 XML 리소스로 정의하는 방법을 보여줍니다.
+</p>
+
+<pre>
+&lt;!-- res/drawable/myanimstatedrawable.xml -->
+&lt;animated-selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ &lt;!-- provide a different drawable for each state-->
+ &lt;item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
+ android:state_pressed="true"/>
+ &lt;item android:id="@+id/focused" android:drawable="@drawable/drawableF"
+ android:state_focused="true"/>
+ &lt;item android:id="@id/default"
+ android:drawable="@drawable/drawableD"/>
+
+ &lt;!-- specify a transition -->
+ &lt;transition android:fromId="@+id/default" android:toId="@+id/pressed">
+ &lt;animation-list>
+ &lt;item android:duration="15" android:drawable="@drawable/dt1"/>
+ &lt;item android:duration="15" android:drawable="@drawable/dt2"/>
+ ...
+ &lt;/animation-list>
+ &lt;/transition>
+ ...
+&lt;/animated-selector>
+</pre>
+
+
+<h2 id="AnimVector">벡터 드로어블 애니메이트</h2>
+
+<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">벡터 드로어블</a>은 정의를 잃지 않고 확대할 수 있습니다.
+ {@link android.graphics.drawable.AnimatedVectorDrawable}
+클래스를 사용하면 Vector Drawable의 속성을 애니메이트할 수 있습니다.</p>
+
+<p>일반적으로 애니메이트된 벡터 드로어블은 다음 3개의 XML 파일에서 정의합니다.</p>
+
+<ul>
+<li>
+<code>res/drawable/</code>의 <code>&lt;vector&gt;</code> 요소를 가진 벡터 드로어블</li>
+<li>
+<code>res/drawable/</code>의 <code>&lt;animated-vector&gt;</code> 요소를 가진 애니메이트된 벡터 드로어블</li>
+<li>
+<code>res/anim/</code>의 <code>&lt;objectAnimator&gt;</code> 요소를 가진 하나 이상의 객체 애니메이터</li>
+</ul>
+
+<p>애니메이트된 벡터 드로어블은 <code>&lt;group&gt;</code> 및
+<code>&lt;path&gt;</code> 요소의 특성을 애니메이트할 수 있습니다. <code>&lt;group&gt;</code> 요소는 경로 또는 하위 그룹 집합을 정의하며, <code>&lt;path&gt;</code> 요소는 그릴 경로를 정의합니다.
+</p>
+
+<p>애니메이트할 벡터 드로어블을 정의하는 경우, 애니메이터 정의에서 참조할 수 있도록 <code>android:name</code>
+특성을 사용하여 그룹 및 경로에 고유한 이름을 할당합니다.
+ 예:</p>
+
+<pre>
+&lt;!-- res/drawable/vectordrawable.xml -->
+&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="600"
+ android:viewportWidth="600">
+ &lt;group
+ <strong>android:name="rotationGroup"</strong>
+ android:pivotX="300.0"
+ android:pivotY="300.0"
+ android:rotation="45.0" >
+ &lt;path
+ <strong>android:name="v"</strong>
+ android:fillColor="#000000"
+ android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
+ &lt;/group>
+&lt;/vector>
+</pre>
+
+<p>애니메이트된 벡터 드로어블 정의는 벡터 드로어블의 그룹 및 경로를 이름으로 참조합니다.
+</p>
+
+<pre>
+&lt;!-- res/drawable/animvectordrawable.xml -->
+&lt;animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vectordrawable" >
+ &lt;target
+ android:name="rotationGroup"
+ android:animation="@anim/rotation" />
+ &lt;target
+ android:name="v"
+ android:animation="@anim/path_morph" />
+&lt;/animated-vector>
+</pre>
+
+<p>애니메이션 정의는 {@link android.animation.ObjectAnimator} 또는 {@link
+android.animation.AnimatorSet} 객체를 나타냅니다. 이 예의 첫 번째 애니메이터는 대상 그룹을 360도 회전합니다.
+</p>
+
+<pre>
+&lt;!-- res/anim/rotation.xml -->
+&lt;objectAnimator
+ android:duration="6000"
+ android:propertyName="rotation"
+ android:valueFrom="0"
+ android:valueTo="360" />
+</pre>
+
+<p>두 번째 애니메이터는 벡터 드로어블의 경로를 다른 모양으로 모핑합니다.
+ 두 경로 모두 모핑이 가능해야 하며, 같은 수의 명령어와 각 명령어에 대해 같은 수의 매개변수가 있어야 합니다.
+</p>
+
+<pre>
+&lt;!-- res/anim/path_morph.xml -->
+&lt;set xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;objectAnimator
+ android:duration="3000"
+ android:propertyName="pathData"
+ android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
+ android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
+ android:valueType="pathType" />
+&lt;/set>
+</pre>
+
+<p>자세한 내용은 {@link
+android.graphics.drawable.AnimatedVectorDrawable}의 API 레퍼런스를 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/training/material/compatibility.jd b/docs/html-intl/intl/ko/training/material/compatibility.jd
new file mode 100644
index 000000000000..266cd7c62f9b
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/compatibility.jd
@@ -0,0 +1,168 @@
+page.title=호환성 유지
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#Theme">대체 스타일 정의</a></li>
+ <li><a href="#Layouts">대체 레이아웃 제공</a></li>
+ <li><a href="#SupportLib">지원 라이브러리 사용</a></li>
+ <li><a href="#CheckVersion">시스템 버전 확인</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>머티리얼 테마 및 사용자지정 액티비티 전환과 같은 일부 머티리얼 디자인 기능은 Android 5.0(API 레벨 21) 이상에서만 이용할 수 있습니다.
+ 그러나 머티리얼 디자인을 지원하는 기기에서 실행할 경우 이러한 기능을 사용하면서도 이전 버전의 Android를 실행하는 기기와도 호환되도록 앱을 디자인할 수 있습니다.
+
+</p>
+
+
+<h2 id="Theme">대체 스타일 정의</h2>
+
+<p>머티리얼 테마를 지원하는 기기에서 해당 테마를 사용하고, 이전 버전의 Android를 실행하는 기기에서 구버전의 테마로 되돌리도록 앱을 구성할 수 있습니다.
+</p>
+
+<ol>
+<li>
+<code>res/values/styles.xml</code>에서 구버전의 테마에서 상속된 테마(Holo 등)를 정의합니다.</li>
+<li>
+<code>res/values-v21/styles.xml</code>에서 머티리얼 테마에서 상속된, 같은 이름을 가진 테마를 정의합니다.</li>
+<li>매니페스트 파일에서 이 테마를 앱의 테마로 설정합니다.</li>
+</ol>
+
+<p class="note"><strong>참고:</strong>
+앱이 머티리얼 테마를 사용하지만 이러한 방식으로 대체 테마를 제공하지 않으면 Android 5.0 이전 버전에서는 앱이 실행되지 않습니다.
+
+</p>
+
+
+<h2 id="Layouts">대체 레이아웃 제공</h2>
+
+<p>머티리얼 디자인 지침에 따라 디자인한 레이아웃이 Android 5.0(API 레벨 21)에서 새로 도입된 XML 특성을 사용하지 않는 경우, 해당 레이아웃은 이전 버전의 Android에서 실행됩니다.
+
+ 그렇지 않은 경우 대체 레이아웃을 제공할 수 있습니다. 또한 이전 버전의 Android에서 앱이 표시되는 방식을 사용자가 지정할 수 있는 대체 레이아웃을 제공할 수도 있습니다.
+</p>
+
+<p><code>res/layout-v21/</code> 안에서 Android 5.0(API 레벨 21)의 레이아웃 파일을 생성하고, <code>res/layout/</code> 안에서 이전 버전의 Android를 위한 대체 레이아웃 파일을 생성합니다.
+예를 들어, <code>res/layout/my_activity.xml</code>은
+<code>res/layout-v21/my_activity.xml</code>의 대체 레이아웃입니다.
+</p>
+
+<p>코드의 중복을 피하기 위해 <code>res/values/</code> 안에서 스타일을 정의하고, 새 API에 대해 <code>res/values-v21/</code>에서 스타일을 수정하고, 스타일 상속을 사용하여 <code>res/values/</code>에서 기본 스타일을 정의하고 <code>res/values-v21/</code>에서 해당 스타일로부터 상속합니다.
+
+</p>
+
+
+<h2 id="SupportLib">지원 라이브러리 사용</h2>
+
+<p><a href="{@docRoot}tools/support-library/features.html#v7">v7 Support Libraries</a>
+ r21 이상에는 다음과 같은 머티리얼 디자인 기능이 포함되어 있습니다.</p>
+
+<ul>
+<li><code>Theme.AppCompat</code> 테마 중 하나를 적용할 때 일부 시스템 위젯에
+대한 <a href="{@docRoot}training/material/theme.html">머티리얼 디자인 스타일</a></li>
+<li><code>Theme.AppCompat</code> 테마의 <a href="{@docRoot}training/material/theme.html#ColorPalette">색상표 테마 특성</a>
+</li>
+<li><a href="{@docRoot}training/material/lists-cards.html#RecyclerView">데이터 컬렉션 표시</a>를 위한 {@link android.support.v7.widget.RecyclerView} 위젯
+</li>
+<li><a href="{@docRoot}training/material/lists-cards.html#CardView">카드 생성</a>을 위한 {@link android.support.v7.widget.CardView} 위젯</li>
+<li><a href="{@docRoot}training/material/drawables.html#ColorExtract">이미지에서 주요 색상을 추출</a>하기 위한 {@link android.support.v7.graphics.Palette} 클래스
+</li>
+</ul>
+
+<h3>시스템 위젯</h3>
+
+<p><code>Theme.AppCompat</code> 테마는 다음 위젯에 대한 머티리얼 디자인 스타일을 제공합니다.</p>
+
+<ul>
+ <li>{@link android.widget.EditText}</li>
+ <li>{@link android.widget.Spinner}</li>
+ <li>{@link android.widget.CheckBox}</li>
+ <li>{@link android.widget.RadioButton}</li>
+ <li>{@link android.support.v7.widget.SwitchCompat}</li>
+ <li>{@link android.widget.CheckedTextView}</li>
+</ul>
+
+<h3>색상표</h3>
+
+<p>Android v7 지원 라이브러리에서 머티리얼 디자인 스타일을 가져와서 색상표를 사용자지정하려면 <code>Theme.AppCompat</code> 테마 중 하나를 적용합니다.
+</p>
+
+<pre>
+&lt;!-- extend one of the Theme.AppCompat themes -->
+&lt;style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
+ &lt;!-- customize the color palette -->
+ &lt;item name="colorPrimary">@color/material_blue_500&lt;/item>
+ &lt;item name="colorPrimaryDark">@color/material_blue_700&lt;/item>
+ &lt;item name="colorAccent">@color/material_green_A200&lt;/item>
+&lt;/style>
+</pre>
+
+<h3>목록 및 카드</h3>
+
+<p>{@link android.support.v7.widget.RecyclerView} 및 {@link
+android.support.v7.widget.CardView} 위젯은 Android v7 지원 라이브러리를 통해 이전 버전의 Android에서 사용할 수 있지만, 다음과 같은 제약이 있습니다.
+</p>
+<ul>
+<li>{@link android.support.v7.widget.CardView}는 추가 패딩을 사용하여 프로그래밍 방식의 그림자 구현으로 환원됩니다.
+</li>
+<li>{@link android.support.v7.widget.CardView}는 둥근 모서리와 교차하는 하위 뷰를 클리핑하지 않습니다.
+</li>
+</ul>
+
+
+<h3>종속 사항</h3>
+
+<p>Android 5.0(API 레벨 21) 이전 버전에서 이러한 기능을 사용하려면 프로젝트에 Android v7 지원 라이브러리를 <a href="{@docRoot}/sdk/installing/studio-build.html#dependencies">Gradle 종속 사항</a>으로 포함합니다.
+</p>
+
+<pre>
+dependencies {
+ compile 'com.android.support:appcompat-v7:21.0.+'
+ compile 'com.android.support:cardview-v7:21.0.+'
+ compile 'com.android.support:recyclerview-v7:21.0.+'
+}
+</pre>
+
+
+<h2 id="CheckVersion">시스템 버전 확인</h2>
+
+<p>다음 기능은 Android 5.0(API 레벨 21) 이상에서만 사용할 수 있습니다.</p>
+
+<ul>
+<li>액티비티 전환</li>
+<li>터치 피드백</li>
+<li>애니메이션 표시</li>
+<li>경로기반 애니메이션</li>
+<li>벡터 드로어블</li>
+<li>드로어블 색조 적용</li>
+</ul>
+
+<p>이전 버전 Android와 호환성을 유지하려면, 이러한 기능을 위한 API를 호출하기 전에 런타임에 시스템 {@link
+android.os.Build.VERSION#SDK_INT version}을 확인하세요.
+</p>
+
+<pre>
+// Check if we're running on Android 5.0 or higher
+if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // Call some material design APIs here
+} else {
+ // Implement this feature without material design
+}
+</pre>
+
+<p class="note"><strong>참고:</strong> 앱에서 어떤 버전의 Android를 지원할지 지정하려면 매니페스트 파일에서 <code>android:minSdkVersion</code> 및 <code>android:targetSdkVersion</code>
+특성을 사용하세요.
+ Android 5.0에서 머티어리얼 디자인 기능을 사용하려면 <code>android:targetSdkVersion</code> 특성을 <code>21</code>로 설정하세요.
+ 자세한 내용은 <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt; API 가이드</a>를 참조하세요.
+
+</p>
diff --git a/docs/html-intl/intl/ko/training/material/drawables.jd b/docs/html-intl/intl/ko/training/material/drawables.jd
new file mode 100644
index 000000000000..18d5bf840394
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/drawables.jd
@@ -0,0 +1,126 @@
+page.title=드로어블 사용
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#DrawableTint">드로어블 리소스 색조 적용</a></li>
+ <li><a href="#ColorExtract">이미지에서 주요 색상 추출</a></li>
+ <li><a href="#VectorDrawables">벡터 드로어블 생성</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+<p>드로어블의 다음 기능은 앱에서 머티리얼 디자인을 구현하는 데 도움이 됩니다.</p>
+
+<ul>
+<li>드로어블 색조 적용</li>
+<li>주요 색상 추출</li>
+<li>벡터 드로어블</li>
+</ul>
+
+<p>이 과정은 앱에서 이러한 기능을 사용하는 방법을 보여줍니다.</p>
+
+
+<h2 id="DrawableTint">드로어블 리소스 색조 적용</h2>
+
+<p>Android 5.0(API 레벨 21) 이상에서는 알파 마스크로 정의된 비트맵 및 나인패치에 색조를 적용할 수 있습니다.
+ 색상 리소스 또는 색상 리소스로 변환되는 테마 특성(예: <code>?android:attr/colorPrimary</code>)을 사용하여 색조를 적용할 수 있습니다.
+ 일반적으로 이러한 자산은 한 번만 생성하며 자동으로 채색되어 테마와 일치하게 됩니다.
+</p>
+
+<p>{@code setTint()} 메서드를 사용하여 {@link android.graphics.drawable.BitmapDrawable} 또는 {@link
+android.graphics.drawable.NinePatchDrawable} 객체에 색조를 적용할 수 있습니다. 또한
+<code>android:tint</code> 및 <code>android:tintMode</code> 특성으로 레이아웃에 색조 색상과 모드를 설정할 수 있습니다.
+</p>
+
+
+<h2 id="ColorExtract">이미지에서 주요 색상 추출</h2>
+
+<p>Android 지원 라이브러리 r21 이상에는 이미지에서 주요 색상을 추출할 수 있는 {@link
+android.support.v7.graphics.Palette} 클래스가 있습니다. 이 클래스는 다음과 같은 주요 색상을 추출합니다.
+</p>
+
+<ul>
+<li>생생한 색상</li>
+<li>생생한 어두운 색상</li>
+<li>생생한 밝은 색상</li>
+<li>차분한 색상</li>
+<li>차분하고 어두운 색상</li>
+<li>차분하고 밝은 색상</li>
+</ul>
+
+<p>이러한 색상을 추출하려면, 이미지를 불러올 배경 스레드에서
+{@link android.support.v7.graphics.Palette#generate Palette.generate()} 정적 메서드로 {@link android.graphics.Bitmap} 객체를 전달합니다.
+ 스레드를 사용할 수 없는 경우, 대신
+{@link android.support.v7.graphics.Palette#generateAsync Palette.generateAsync()} 메서드를 호출하고 Listener를 제공합니다.
+</p>
+
+<p><code>Palette.getVibrantColor</code>와 같은
+<code>Palette</code> 클래스의 getter 메서드를 사용하여 이미지에서 주요 색상을 추출할 수 있습니다.</p>
+
+<p>프로젝트에서 {@link android.support.v7.graphics.Palette} 클래스를 사용하려면 다음
+<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle 종속 사항을</a>를 앱의 모듈에 추가합니다.
+</p>
+
+<pre>
+dependencies {
+ ...
+ compile 'com.android.support:palette-v7:21.0.0'
+}
+</pre>
+
+<p>자세한 내용은 {@link android.support.v7.graphics.Palette}
+클래스의 API 레퍼런스를 참조하세요.</p>
+
+
+<h2 id="VectorDrawables">벡터 드로어블 생성</h2>
+
+<!-- video box -->
+<a class="notice-developers-video" href="https://www.youtube.com/watch?v=wlFVIIstKmA" style="margin-top:18px">
+<div>
+ <h3>비디오</h3>
+ <p>Android 벡터 그래픽</p>
+</div>
+</a>
+
+<p>Android 5.0(API 레벨 21) 이상에서는 정의를 잃지 않고 배율을 조정하는 벡터 드로어블을 정의할 수 있습니다.
+ 비트맵 이미지의 경우 각 화면 밀도마다 자산 파일이 필요한 반면, 벡터 이미지의 경우에는 하나의 자산 파일만 필요합니다.
+ 벡터 이미지를 생성하려면 <code>&lt;vector&gt;</code> XML 요소 안에 모양의 세부정보를 정의합니다.
+</p>
+
+<p>다음 예에서는 하트 모양을 가진 벡터 이미지를 정의합니다.</p>
+
+<pre>
+&lt;!-- res/drawable/heart.xml -->
+&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
+ &lt;!-- intrinsic size of the drawable -->
+ android:height="256dp"
+ android:width="256dp"
+ &lt;!-- size of the virtual canvas -->
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+
+ &lt;!-- draw a path -->
+ &lt;path android:fillColor="#8fff"
+ android:pathData="M20.5,9.5
+ c-1.955,0,-3.83,1.268,-4.5,3
+ c-0.67,-1.732,-2.547,-3,-4.5,-3
+ C8.957,9.5,7,11.432,7,14
+ c0,3.53,3.793,6.257,9,11.5
+ c5.207,-5.242,9,-7.97,9,-11.5
+ C25,11.432,23.043,9.5,20.5,9.5z" />
+&lt;/vector>
+</pre>
+
+<p>벡터 이미지는 Android에서 {@link android.graphics.drawable.VectorDrawable}
+객체로 나타납니다. <code>pathData</code> 구문에 대한 자세한 내용은 <a href="http://www.w3.org/TR/SVG11/paths.html#PathData">SVG Path reference</a>를 참조하세요. 벡터 드로어블의 속성 애니메이트에 대한 자세한 내용은
+<a href="{@docRoot}training/material/animations.html#AnimVector">벡터 드로어블 애니메이트</a>를 참조하세요.
+</p>
diff --git a/docs/html-intl/intl/ko/training/material/get-started.jd b/docs/html-intl/intl/ko/training/material/get-started.jd
new file mode 100644
index 000000000000..be1fca2500d6
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/get-started.jd
@@ -0,0 +1,171 @@
+page.title=시작하기
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#ApplyTheme">머티리얼 테마 적용</a></li>
+ <li><a href="#Layouts">레이아웃 디자인</a></li>
+ <li><a href="#Depth">뷰에서 엘리베이션 지정</a></li>
+ <li><a href="#ListsCards">목록 및 카드 생성</a></li>
+ <li><a href="#Animations">애니메이션 사용자지정</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>머티리얼 디자인으로 앱을 생성하려면:</p>
+
+<ol>
+ <li style="margin-bottom:10px">
+ <a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a>을 검토합니다.</li>
+ <li style="margin-bottom:10px">
+ 앱에 머티리얼 <strong>테마</strong>를 적용합니다.</li>
+ <li style="margin-bottom:10px">
+ 머티리얼 디자인 지침에 따라 <strong>레이아웃</strong>을 생성합니다.</li>
+ <li style="margin-bottom:10px">
+ 그림자를 드리우기 위한 뷰의 <strong>엘리베이션</strong>을 지정합니다.</li>
+ <li style="margin-bottom:10px">
+ 목록 및 카드에는 시스템 <strong>위젯</strong>을 사용합니다.</li>
+ <li style="margin-bottom:10px">
+ 앱에서 <strong>애니메이션</strong>을 사용자지정합니다.</li>
+</ol>
+
+<h3>이전 버전과의 호환성 유지</h3>
+
+<p>Android 5.0 이전 버전과의 호환성을 유지하면서 다양한 머티리얼 디자인 기능을 앱에 추가할 수 있습니다.
+ 자세한 내용은
+<a href="{@docRoot}training/material/compatibility.html">호환성 유지</a>를 참조하세요.</p>
+
+<h3>머티리얼 디자인으로 앱 업데이트</h3>
+
+<p>머티리얼 디자인을 통합하기 위해 기존 앱을 업데이트하려면 머티리얼 디자인 지침에 따라 레이아웃을 업데이트하세요.
+ 또한 깊이, 터치 피드백, 애니메이션도 통합하세요.
+</p>
+
+<h3>머티리얼 디자인으로 새 앱 생성</h3>
+
+<p>머티리얼 디자인 기능으로 새 앱을 생성하는 경우, <a href="http://www.google.com/design/spec">머티리얼 디자인 지침</a>은 효율적인 디자인 프레임워크를 제공합니다.
+ 앱 디자인 및 개발 시 이 지침을 따르고 Android 프레임워크의 새로운 기능을 사용하세요.
+</p>
+
+
+<h2 id="ApplyTheme">머티리얼 테마 적용</h2>
+
+<p>머티리얼 테마를 앱에 적용하려면
+<code>android:Theme.Material</code>에서 상속하는 스타일을 지정합니다.</p>
+
+<pre>
+&lt;!-- res/values/styles.xml -->
+&lt;resources>
+ &lt;!-- your theme inherits from the material theme -->
+ &lt;style name="AppTheme" parent="android:Theme.Material">
+ &lt;!-- theme customizations -->
+ &lt;/style>
+&lt;/resources>
+</pre>
+
+<p>머티리얼 테마는 터치 피드백 및 액티비티 전환을 위한 색상표 및 기본 애니메이션을 설정할 수 있는 업데이트된 시스템 위젯을 제공합니다.
+ 자세한 내용은
+<a href="{@docRoot}training/material/theme.html">머티리얼 테마 사용</a>을 참조하세요.</p>
+
+
+<h2 id="Layouts">레이아웃 디자인</h2>
+
+<p>머티리얼 테마를 적용하고 사용자지정하는 것과 더불어, 레이아웃이 <a href="http://www.google.com/design/spec">머티리얼 디자인 지침</a>을 따라야 합니다.
+ 레이아웃 디자인 시 다음 사항에 특히 주의하세요.
+</p>
+
+<ul>
+<li>기준선 그리드</li>
+<li>키라인</li>
+<li>간격</li>
+<li>터치 대상 크기</li>
+<li>레이아웃 구조</li>
+</ul>
+
+
+<h2 id="Depth">뷰에서 엘리베이션 지정</h2>
+
+<p>뷰는 그림자를 드리울 수 있으며 뷰의 엘리베이션 값은 그림자 크기 및 그리는 순서를 결정합니다.
+ 뷰의 엘리베이션을 설정하려면 레이아웃에서
+<code>android:elevation</code> 특성을 사용하세요.</p>
+
+<pre>
+&lt;TextView
+ android:id="&#64;+id/my_textview"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="&#64;string/next"
+ android:background="&#64;color/white"
+ android:elevation="5dp" />
+</pre>
+
+<p>새 <code>translationZ</code> 속성을 사용하여 뷰 엘리베이션의 일시적 변경을 반영하는 애니메이션을 생성할 수 있습니다.
+ 엘리베이션 변경은
+<a href="{@docRoot}training/material/animations.html#ViewState">터치
+제스처에 반응</a>할 때 유용하게 쓰일 수 있습니다.</p>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/shadows-clipping.html">그림자 정의 및 뷰 클리핑</a>을 참조하세요.
+</p>
+
+
+<h2 id="ListsCards">목록 및 카드 생성</h2>
+
+<p>{@link android.support.v7.widget.RecyclerView}는 {@link
+android.widget.ListView}의 플러그 기능이 개선된 버전으로, 다양한 레이아웃 유형을 지원하고 향상된 성능을 제공합니다.
+{@link android.support.v7.widget.CardView}를 사용하면 모든 앱에서 일관된 모습으로 카드 안의 정보를 표시할 수 있습니다.
+ 다음 코드 예는 {@link android.support.v7.widget.CardView}를 레이아웃에
+포함시키는 방법을 보여줍니다.</p>
+
+<pre>
+&lt;android.support.v7.widget.CardView
+ android:id="&#64;+id/card_view"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ card_view:cardCornerRadius="3dp">
+ ...
+&lt;/android.support.v7.widget.CardView>
+</pre>
+
+<p>자세한 내용은 <a href="{@docRoot}training/material/lists-cards.html">목록 및 카드 생성</a>을 참조하세요.
+</p>
+
+
+<h2 id="Animations">애니메이션 사용자지정</h2>
+
+<p>Android 5.0(API 레벨 21)에는 앱에서 사용자지정 애니메이션 생성을 위한 새 API가 포함되어 있습니다. 예를 들어, 액티비티 전환을 활성화하고 액티비티 내부에서 나가기 전환을 정의할 수 있습니다.
+
+</p>
+
+<pre>
+public class MyActivity extends Activity {
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // enable transitions
+ getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+ setContentView(R.layout.activity_my);
+ }
+
+ public void onSomeButtonClicked(View view) {
+ getWindow().setExitTransition(new Explode());
+ Intent intent = new Intent(this, MyOtherActivity.class);
+ startActivity(intent,
+ ActivityOptions
+ .makeSceneTransitionAnimation(this).toBundle());
+ }
+}
+</pre>
+
+<p>이 액티비티에서 다른 액티비티를 시작하면 나가기 전환이 활성화됩니다.</p>
+
+<p>새 애니메이션 API에 대한 자세한 내용은 <a href="{@docRoot}training/material/animations.html">사용자지정 애니메이션 정의</a>를 참조하세요.</p>
diff --git a/docs/html-intl/intl/ko/training/material/index.jd b/docs/html-intl/intl/ko/training/material/index.jd
new file mode 100644
index 000000000000..3dfb5140cb66
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/index.jd
@@ -0,0 +1,61 @@
+page.title=개발자를 위한 머티리얼 디자인
+page.type=design
+page.image=images/cards/material_2x.png
+page.metaDescription=Learn how to apply material design to your apps.
+
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>종속 사항 및 전제조건</h2>
+ <ul>
+ <li>Android 5.0(API 레벨 21)</li>
+ </ul>
+</div>
+</div>
+
+<p>머티리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및 상호 작용 디자인에 대한 종합적인 지침입니다.
+ Android 앱에서 머티리얼 디자인을 사용하려면
+<a href="http://www.google.com/design/spec/material-design/introduction.html">머티리얼 디자인 사양</a>에 설명된 지침을 따르고 Android 5.0(API 레벨 21)에서 제공되는 새 구성 요소 및 기능들을 활용하세요.
+
+
+</p>
+
+<p>이 클래스에서는 다음 요소를 사용하여 머티리얼 디자인 앱을 만드는 방법을 보여줍니다.</p>
+
+<ul>
+<li>머티리얼 테마</li>
+<li>목록 및 카드용 위젯</li>
+<li>사용자지정 그림자 및 뷰 클리핑</li>
+<li>벡터 드로어블</li>
+<li>사용자지정 애니메이션</li>
+</ul>
+
+<p>또한 이 클래스에서는 앱에서 머티리얼 디자인 기능을 사용할 때
+Android 5.0(API 레벨 21) 이전 버전과의 호환성을 유지하는 방법도 배웁니다.</p>
+
+<h2>과정</h2>
+
+<dl>
+ <dt><a href="{@docRoot}training/material/get-started.html">시작하기</a></dt>
+ <dd>머티리얼 디자인 기능을 사용하여 앱을 업데이트하는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/theme.html">머티리얼 테마 사용</a></dt>
+ <dd>앱에 머티리얼 디자인 스타일을 적용하는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/lists-cards.html">목록 및 카드 생성</a></dt>
+ <dd>시스템 위젯을 사용하여 일관된 모양과 느낌을 가진 목록과 카드를 만드는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/shadows-clipping.html">그림자 정의 및 뷰 클리핑</a></dt>
+ <dd>뷰에 대한 엘리베이션을 설정하여 사용자지정 그림자를 생성하는 방법과 뷰를 클리핑하는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/drawables.html">드로어블 사용</a></dt>
+ <dd>벡터 드로어블을 생성하는 방법과 드로어블 리소스를 채색하는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/animations.html">사용자지정 애니메이션 정의</a></dt>
+ <dd>공유 요소를 사용하여 뷰 및 액티비티 전환을 위한 사용자지정 애니메이션을 생성하는 방법을 배웁니다.</dd>
+
+ <dt><a href="{@docRoot}training/material/compatibility.html">호환성 유지</a></dt>
+ <dd>Android 5.0 이전 버전 플랫폼과의 호환성을 유지하는 방법을 배웁니다.</dd>
+</dl>
diff --git a/docs/html-intl/intl/ko/training/material/lists-cards.jd b/docs/html-intl/intl/ko/training/material/lists-cards.jd
new file mode 100644
index 000000000000..28fdf22cfae0
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/lists-cards.jd
@@ -0,0 +1,266 @@
+page.title=목록 및 카드 생성
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#RecyclerView">목록 생성</a></li>
+ <li><a href="#CardView">카드 생성</a></li>
+ <li><a href="#Dependencies">종속 사항 추가</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>앱에서 머티리얼 디자인 스타일로 복잡한 목록과 카드를 생성하려면
+{@link android.support.v7.widget.RecyclerView} 및 {@link android.support.v7.widget.CardView}
+위젯을 사용하세요.</p>
+
+
+<h2 id="RecyclerView">목록 생성</h2>
+
+<p>{@link android.support.v7.widget.RecyclerView} 위젯은 {@link android.widget.ListView}의 더욱 향상되고 유연해진 버전입니다.
+ 이 위젯은 한정된 수의 뷰를 유지함으로써 매우 효율적으로 스크롤할 수 있는 큰 데이터 집합을 표시하기 위한 컨테이너입니다.
+ 사용자 작업 또는 네트워크 이벤트에 따라 런타임에 요소가 변경되는 데이터 컬렉션이 있는 경우
+{@link android.support.v7.widget.RecyclerView} 위젯을 사용하세요.
+</p>
+
+<p>{@link android.support.v7.widget.RecyclerView} 클래스는 다음 기능을 제공하여 큰 데이터 집합의 표시 및 취급 작업을 단순화합니다.
+</p>
+
+<ul>
+ <li>항목 위치 지정을 위한 레이아웃 관리자</li>
+ <li>항목 제거 및 추가와 같은 공통 항목 작업을 위한 기본 애니메이션</li>
+</ul>
+
+<p>또한 필요에 따라 {@link
+android.support.v7.widget.RecyclerView} 위젯을 위한 사용자지정 레이아웃 관리자 및 애니메이션을 정의할 수도 있습니다.</p>
+
+<img src="{@docRoot}training/material/images/RecyclerView.png" alt="" width="550" height="106" />
+<p class="img-caption">
+<strong>그림 1</strong>. <code>RecyclerView</code> 위젯.
+</p>
+
+<p>{@link android.support.v7.widget.RecyclerView} 위젯을 사용하려면 어댑터와 레이아웃 관리자를 지정해야 합니다.
+ 어댑터를 생성하려면 {@link
+android.support.v7.widget.RecyclerView.Adapter RecyclerView.Adapter} 클래스를 확장하세요. 구현 세부사항은 데이터 집합의 사양 및 뷰 유형에 의해 결정됩니다.
+ 자세한 내용은 아래의 <a href="#RVExamples">예</a>를 참조하세요.
+</p>
+
+<div style="float:right">
+<img src="{@docRoot}design/material/images/list_mail.png" alt="" width="250" height="426" />
+<p class="img-caption" style="margin-left:8px">
+<strong>그림 2</strong> - <code>RecyclerView</code>를 사용한 목록.
+</p>
+</div>
+
+<p><strong>레이아웃 관리자</strong>는 항목 뷰를 {@link
+android.support.v7.widget.RecyclerView}내에 배치하고, 사용자에게는 더 이상 보이지 않는 항목 뷰를 언제 재사용할지 결정합니다.
+ 뷰를 재사용 (또는 <em>재활용</em>)하기 위해, 레이아웃 관리자는 어댑터에게 뷰의 콘텐츠를 데이터 집합의 다른 요소로 교체하도록 요청할 수 있습니다.
+ 이런 방식으로 뷰를 재활용하면 불필요한 뷰 생성이나 리소스를 많이 소모하는 {@link android.app.Activity#findViewById findViewById()} 조회를 수행하지 않아도 되므로 성능이 개선됩니다.
+
+</p>
+
+<p>{@link android.support.v7.widget.RecyclerView}는 다음과 같은 내장 레이아웃 관리자를 제공합니다.</p>
+
+<ul>
+<li>{@link android.support.v7.widget.LinearLayoutManager}는 항목을 가로 또는 세로 스크롤 목록으로 표시합니다.
+</li>
+<li>{@link android.support.v7.widget.GridLayoutManager}는 그리드 형식으로 항목을 표시합니다.</li>
+<li>{@link android.support.v7.widget.StaggeredGridLayoutManager}는 지그재그형의 그리드 형식으로 항목을 표시합니다.</li>
+</ul>
+
+<p>사용자지정 레이아웃 관리자를 생성하려면 {@link
+android.support.v7.widget.RecyclerView.LayoutManager RecyclerView.LayoutManager} 클래스를 확장하십시오.</p>
+
+<h3>애니메이션</h3>
+
+<p>항목 추가 및 제거를 위한 애니메이션은 {@link
+android.support.v7.widget.RecyclerView}에서 기본적으로 활성화됩니다. 이러한 애니메이션을 사용자지정하려면
+{@link android.support.v7.widget.RecyclerView.ItemAnimator RecyclerView.ItemAnimator} 클래스를
+확장하고 {@link android.support.v7.widget.RecyclerView#setItemAnimator RecyclerView.setItemAnimator()}
+메서드를 사용하세요.</p>
+
+<h3 id="RVExamples">예:</h3>
+
+<p>다음 코드 예는
+{@link android.support.v7.widget.RecyclerView}를 레이아웃에 추가하는 방법을 보여줍니다.</p>
+
+<pre>
+&lt;!-- A RecyclerView with some commonly used attributes -->
+&lt;android.support.v7.widget.RecyclerView
+ android:id="@+id/my_recycler_view"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</pre>
+
+<p>{@link android.support.v7.widget.RecyclerView} 위젯을 레이아웃에 추가한 후, 객체 핸들을 얻어 레이아웃 관리자에 연결하고, 표시할 데이터의 어댑터를 첨부합니다.
+
+</p>
+
+<pre>
+public class MyActivity extends Activity {
+ private RecyclerView mRecyclerView;
+ private RecyclerView.Adapter mAdapter;
+ private RecyclerView.LayoutManager mLayoutManager;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.my_activity);
+ mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
+
+ // use this setting to improve performance if you know that changes
+ // in content do not change the layout size of the RecyclerView
+ mRecyclerView.setHasFixedSize(true);
+
+ // use a linear layout manager
+ mLayoutManager = new LinearLayoutManager(this);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+
+ // specify an adapter (see also next example)
+ mAdapter = new MyAdapter(myDataset);
+ mRecyclerView.setAdapter(mAdapter);
+ }
+ ...
+}
+</pre>
+
+<p>어댑터는 데이터 집합의 항목에 액세스할 수 있게 해주며, 항목 뷰를 생성하고, 원래의 항목이 더 이상 보이지 않을 경우 일부 뷰의 콘텐츠를 새 데이터 항목으로 교체합니다.
+
+ 다음 코드 예는 {@link android.widget.TextView} 위젯을 사용하여 표시된 문자열 배열로 이루어진 데이터 집합의 간단한 구현을 보여줍니다.
+</p>
+
+<pre>
+public class MyAdapter extends RecyclerView.Adapter&lt;MyAdapter.ViewHolder> {
+ private String[] mDataset;
+
+ // Provide a reference to the views for each data item
+ // Complex data items may need more than one view per item, and
+ // you provide access to all the views for a data item in a view holder
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ // each data item is just a string in this case
+ public TextView mTextView;
+ public ViewHolder(TextView v) {
+ super(v);
+ mTextView = v;
+ }
+ }
+
+ // Provide a suitable constructor (depends on the kind of dataset)
+ public MyAdapter(String[] myDataset) {
+ mDataset = myDataset;
+ }
+
+ // Create new views (invoked by the layout manager)
+ &#64;Override
+ public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
+ int viewType) {
+ // create a new view
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.my_text_view, parent, false);
+ // set the view's size, margins, paddings and layout parameters
+ ...
+ ViewHolder vh = new ViewHolder(v);
+ return vh;
+ }
+
+ // Replace the contents of a view (invoked by the layout manager)
+ &#64;Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ // - get element from your dataset at this position
+ // - replace the contents of the view with that element
+ holder.mTextView.setText(mDataset[position]);
+
+ }
+
+ // Return the size of your dataset (invoked by the layout manager)
+ &#64;Override
+ public int getItemCount() {
+ return mDataset.length;
+ }
+}
+</pre>
+
+
+<div style="float:right;margin-top:15px;margin-left:30px">
+<img src="{@docRoot}design/material/images/card_travel.png" alt="" width="225" height="383">
+<p class="img-caption" style="margin-left:12px">
+<strong>그림 3</strong>. 카드 예.
+</p>
+</div>
+
+<h2 id="CardView">카드 생성</h2>
+
+<p>{@link android.support.v7.widget.CardView}는 {@link android.widget.FrameLayout} 클래스를
+확장하고 카드 내의 정보를 플랫폼에서 일관된 모습으로 표시할 수 있도록 합니다. {@link
+android.support.v7.widget.CardView} 위젯은 그림자와 둥근 모서리를 가질 수 있습니다.</p>
+
+<p>그림자가 있는 카드를 생성하려면 <code>card_view:cardElevation</code> 특성을 사용합니다.
+{@link android.support.v7.widget.CardView}는 Android 5.0(API 레벨 21) 이상에서 실제 엘리베이션 및 동적 그림자를 사용하며, 이전 버전에서는 이전의 프로그래밍 방식의 그림자 구현으로 환원됩니다. 자세한 내용은 <a href="{@docRoot}training/material/compatibility.html">호환성 유지</a>를 참조하세요.
+
+
+</p>
+
+<p>이러한 속성을 사용하여
+{@link android.support.v7.widget.CardView} 위젯의 모습을 사용자지정합니다.</p>
+
+<ul>
+ <li>레이아웃에 모서리 반지름을 설정하려면 <code>card_view:cardCornerRadius</code>
+특성을 사용합니다.</li>
+ <li>코드에서 모서리 반지름을 설정하려면 <code>CardView.setRadius</code> 메서드를 사용합니다.</li>
+ <li>카드의 배경색을 설정하려면 <code>card_view:cardBackgroundColor</code>
+특성을 사용합니다.</li>
+</ul>
+
+<p>다음 코드 예는 {@link android.support.v7.widget.CardView}
+위젯을 레이아웃에 포함시키는 방법을 보여줍니다.</p>
+
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ ... >
+ &lt;!-- A CardView that contains a TextView -->
+ &lt;android.support.v7.widget.CardView
+ xmlns:card_view="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/card_view"
+ android:layout_gravity="center"
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ card_view:cardCornerRadius="4dp">
+
+ &lt;TextView
+ android:id="@+id/info_text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ &lt;/android.support.v7.widget.CardView>
+&lt;/LinearLayout>
+</pre>
+
+<p>자세한 내용은 {@link android.support.v7.widget.CardView}의 API 레퍼런스를 참조하세요.</p>
+
+
+<h2 id="Dependencies">종속 사항 추가</h2>
+
+<p>{@link android.support.v7.widget.RecyclerView} 및 {@link android.support.v7.widget.CardView}
+위젯은 <a href="{@docRoot}tools/support-library/features.html#v7">v7 지원 라이브러리</a>의 일부입니다.
+ 이러한 위젯을 프로젝트에서 사용하려면 다음
+<a href="{@docRoot}sdk/installing/studio-build.html#dependencies">Gradle 종속 사항</a>을 앱의 모듈에 추가하세요.
+</p>
+
+<pre>
+dependencies {
+ ...
+ compile 'com.android.support:cardview-v7:21.0.+'
+ compile 'com.android.support:recyclerview-v7:21.0.+'
+}
+</pre>
diff --git a/docs/html-intl/intl/ko/training/material/shadows-clipping.jd b/docs/html-intl/intl/ko/training/material/shadows-clipping.jd
new file mode 100644
index 000000000000..e04d0c524453
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/shadows-clipping.jd
@@ -0,0 +1,133 @@
+page.title=그림자 정의 및 뷰 클리핑
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#Elevation">뷰에 엘리베이션 지정</a></li>
+ <li><a href="#Shadows">뷰 그림자 및 윤곽선 사용자지정</a></li>
+ <li><a href="#Clip">뷰 클리핑</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+<p>머티어리얼 디자인은 UI 요소에 엘리베이션을 도입합니다. 엘리베이션은 사용자가 각 요소의 상대적 중요성을 이해하고 현재 직면한 작업에 집중할 수 있도록 도와줍니다.
+</p>
+
+<p>Z 속성으로 표현되는 뷰의 엘리베이션은 그림자의 시각적인 모양을 결정합니다. 예를 들어, 더 높은 Z값을 가진 뷰는 더 크고 부드러운 그림자를 드리웁니다.
+ 높은 Z값을 가진 뷰는 낮은 Z값을 가진 뷰를 가립니다. 하지만 뷰의 Z값이 뷰의 크기에 영향을 주지는 않습니다.
+</p>
+
+<p>그림자는 엘리베이트된 뷰의 상위 요소에 의해 그려지며, 따라서 기본적으로 상위 요소에 의해 클리핑되는 표준 뷰 클리핑이 적용됩니다.
+</p>
+
+<p>엘리베이션은 특정 작업 수행 시 위젯이 일시적으로 뷰 평면 위로 올라오는 애니메이션을 생성하는 경우에도 유용합니다.
+</p>
+
+<p>머티리얼 디자인의 엘리베이션에 대한 자세한 내용은
+<a href="http://www.google.com/design/spec/what-is-material/objects-in-3d-space.html">3D 공간의 개체</a>를 참조하세요.
+</p>
+
+
+<h2 id="Elevation">뷰에 엘리베이션 지정</h2>
+
+<p>뷰의 Z 값은 2개의 구성요소를 가집니다.
+
+<ul>
+<li>엘리베이션: 정적 구성요소.</li>
+<li>변환: 애니메이션에 사용되는 동적 구성요소.</li>
+</ul>
+
+<p><code>Z = elevation + translationZ</code></p>
+
+<img src="{@docRoot}training/material/images/shadows-depth.png" width="580" height="261" alt="" />
+<p class="img-caption"><strong>그림 1</strong> - 서로 다른 뷰 엘리베이션의 그림자.</p>
+
+<p>레이아웃 정의에서 뷰의 엘리베이션을 설정하려면 <code>android:elevation</code>
+특성을 사용합니다. 액티비티의 코드에서 뷰의 엘리베이션을 설정하려면
+{@link android.view.View#setElevation View.setElevation()} 메서드를 사용합니다.</p>
+
+<p>뷰의 변환을 설정하려면 {@link android.view.View#setTranslationZ
+View.setTranslationZ()} 메서드를 사용합니다.</p>
+
+<p>새 {@link android.view.ViewPropertyAnimator#z ViewPropertyAnimator.z()} 및 {@link
+android.view.ViewPropertyAnimator#translationZ ViewPropertyAnimator.translationZ()} 메서드를 사용하면 뷰의 엘리베이션을 손쉽게 애니메이트할 수 있습니다.
+ 자세한 내용은
+{@link android.view.ViewPropertyAnimator}의 API 레퍼런스와 <a href="{@docRoot}guide/topics/graphics/prop-animation.html">속성 애니메이션</a> 개발자 가이드를 참조하세요.
+</p>
+
+<p>{@link android.animation.StateListAnimator}를 사용해서 이러한 애니메이션을 선언적 방식으로 지정할 수도 있습니다.
+ 이는 사용자가 버튼을 누를 때와 같이 상태 변경이 애니메이션을 트리거하는 경우에 특히 유용합니다.
+ 자세한 내용은
+<a href="{@docRoot}training/material/animations.html#ViewState">뷰 상태 변경 애니메이트</a>를 참조하세요.</p>
+
+<p>Z 값은 dp(밀도 독립적 픽셀)로 측정됩니다.</p>
+
+
+<h2 id="Shadows">뷰 그림자 및 윤곽선 사용자지정</h2>
+
+<p>뷰의 배경 드로어블의 경계는 해당 그림자의 기본 모양을 결정합니다.
+<strong>윤곽선</strong>은 그래픽 객체의 바깥쪽 모양을 나타내고 터치 피드백의 물결 영역을 정의합니다.
+</p>
+
+<p>배경 드로어블을 사용하여 정의된 다음 뷰를 살펴봅시다.</p>
+
+<pre>
+&lt;TextView
+ android:id="@+id/myview"
+ ...
+ android:elevation="2dp"
+ android:background="@drawable/myrect" />
+</pre>
+
+<p>배경 드로어블은 둥근 모서리를 가진 직사각형으로 정의됩니다.</p>
+
+<pre>
+&lt;!-- res/drawable/myrect.xml -->
+&lt;shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ &lt;solid android:color="#42000000" />
+ &lt;corners android:radius="5dp" />
+&lt;/shape>
+</pre>
+
+<p>배경 드로어블이 뷰의 윤곽선을 정의하기 때문에 뷰는 둥근 모서리를 가진 그림자를 드리웁니다.
+ 사용자지정 윤곽선을 제공하면 뷰 그림자의 기본 모양이 재정의됩니다.</p>
+
+<p>코드에서 뷰의 사용자지정 윤곽선을 정의하려면:<p>
+
+<ol>
+<li>{@link android.view.ViewOutlineProvider} 클래스를 확장합니다.</li>
+<li>{@link android.view.ViewOutlineProvider#getOutline getOutline()} 메서드를 재정의합니다.</li>
+<li>{@link
+android.view.View#setOutlineProvider View.setOutlineProvider()} 메서드를 사용하여 새로운 윤곽선 공급자를 뷰에 할당합니다.</li>
+</ol>
+
+<p>{@link android.graphics.Outline} 클래스의 메서드를 사용하여 둥근 모서리를 가진 타원형 및 직사각형 윤곽선을 생성할 수 있습니다.
+ 뷰의 기본 윤곽선 공급자는 뷰의 배경에서 윤곽선을 가져옵니다.
+ 뷰에 그림자가 드리우는 것을 원치 않으면 뷰의 윤곽선 공급자를 <code>null</code>로 설정하세요.
+</p>
+
+
+<h2 id="Clip">뷰 클리핑</h2>
+
+<p>뷰를 클리핑하면 뷰의 모양을 손쉽게 바꿀 수 있습니다. 다른 디자인 요소와의 일관성을 위해, 또는 사용자 입력에 응답하여 뷰의 모양을 바꾸기 위해 뷰를 클리핑할 수 있습니다. {@link android.view.View#setClipToOutline
+View.setClipToOutline()} 메서드나 <code>android:clipToOutline</code> 특성을 사용하여 뷰를 해당 윤곽선 영역까지 클리핑할 수 있습니다.
+
+
+{@link android.graphics.Outline#canClip Outline.canClip()} 메서드에서 결정된 대로 사각형, 원형 및 둥근 사각형의 윤곽선만 클리핑을 지원합니다.
+</p>
+
+<p>드로어블 모양으로 뷰를 클리핑하려면 위와 같이 드로어블을 뷰의 배경으로
+설정하고 {@link android.view.View#setClipToOutline View.setClipToOutline()}
+메서드를 호출합니다.</p>
+
+<p>뷰 클리핑은 리소스 소모가 많은 작업이므로,뷰를 클리핑하는 데 사용하는 모양을 애니메이트하지 마세요.
+ 이 효과를 얻으려면 <a href="{@docRoot}training/material/animations.html#Reveal">표시 효과</a> 애니메이션을 사용하세요.</p>
diff --git a/docs/html-intl/intl/ko/training/material/theme.jd b/docs/html-intl/intl/ko/training/material/theme.jd
new file mode 100644
index 000000000000..ef4ff5847f1d
--- /dev/null
+++ b/docs/html-intl/intl/ko/training/material/theme.jd
@@ -0,0 +1,131 @@
+page.title=머티리얼 테마 사용
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>이 과정에서 다루는 내용</h2>
+<ol>
+ <li><a href="#ColorPalette">색상표 사용자지정</a></li>
+ <li><a href="#StatusBar">상태 표시줄 사용자지정</a></li>
+ <li><a href="#Inheritance">개별 뷰의 테마 지정</a></li>
+</ol>
+<h2>필독 항목</h2>
+<ul>
+ <li><a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a></li>
+ <li><a href="{@docRoot}design/material/index.html">Android의 머티리얼 디자인</a></li>
+</ul>
+</div>
+</div>
+
+
+<p>새 머티리얼 테마는 다음과 같은 기능을 제공합니다.</p>
+
+<ul>
+ <li>색상표를 설정할 수 있는 시스템 위젯</li>
+ <li>시스템 위젯의 터치 피드백 애니메이션</li>
+ <li>액티비티 전환 애니메이션</li>
+</ul>
+
+<p>제어 중인 색상표로 브랜드 ID에 따라 머티리얼 테마의 모습을 사용자지정할 수 있습니다.
+ <a href="#fig3">그림 3</a>과 같이 테마 특성을 사용하여 작업 표시줄 및 상태 표시줄에 색조를 적용할 수 있습니다.
+</p>
+
+<p>시스템 위젯에는 새 디자인 및 터치 피드백 애니메이션이 있습니다. 앱에서 색상표, 터치 피드백 애니메이션, 액티비티 전환을 사용자지정할 수 있습니다.
+</p>
+
+<p>머티리얼 테마는 다음과 같이 정의됩니다.</p>
+
+<ul>
+ <li><code>@android:style/Theme.Material</code> (어두운 버전)</li>
+ <li><code>@android:style/Theme.Material.Light</code> (밝은 버전)</li>
+ <li><code>@android:style/Theme.Material.Light.DarkActionBar</code></li>
+</ul>
+
+<p>사용가능한 머티리얼 스타일 목록은
+{@link android.R.style R.style}의 API 레퍼런스를 참조하세요.</p>
+
+<!-- two columns, dark/light material theme example -->
+<div style="width:700px;margin-top:25px;margin-bottom:10px">
+<div style="float:left;width:250px;margin-left:40px;margin-right:60px;">
+ <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238">
+ <div style="width:170px;margin:0 auto">
+ <p style="margin-top:8px;font-size:12px"><strong>그림 1</strong>. 어두운 머티리얼 테마</p>
+ </div>
+</div>
+<div style="float:left;width:250px;margin-right:0px;">
+ <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238">
+ <div style="width:170px;margin:0 auto">
+ <p style="margin-top:8px;font-size:12px"><strong>그림 2</strong>. 밝은 머티리얼 테마</p>
+ </div>
+</div>
+<br style="clear:left">
+</div>
+
+<p class="note">
+<strong>참고:</strong> 머티리얼 테마는 Android 5.0(API 레벨 21) 이상에서만 사용할 수 있습니다.
+ <a href="{@docRoot}tools/support-library/features.html#v7">v7 지원 라이브러리</a>
+는 일부 위젯에 머티리얼 디자인 스타일의 테마를 제공하고 색상표 사용자지정을 지원합니다.
+ 자세한 내용은
+<a href="{@docRoot}training/material/compatibility.html">호환성 유지</a>를 참조하세요.
+</p>
+
+
+<h2 id="ColorPalette">색상표 사용자지정</h2>
+
+<p style="margin-bottom:30px">테마의 기본 색상을 브랜드에 맞게 사용자지정하려면 머티리얼 테마에서 상속 시 테마 특성을 사용하여 사용자지정 색상을 정의합니다.
+</p>
+
+<pre>
+&lt;resources>
+ &lt;!-- inherit from the material theme -->
+ &lt;style name="AppTheme" parent="android:Theme.Material">
+ &lt;!-- Main theme colors -->
+ &lt;!-- your app branding color for the app bar -->
+ &lt;item name="android:colorPrimary">@color/primary&lt;/item>
+ &lt;!-- darker variant for the status bar and contextual app bars -->
+ &lt;item name="android:colorPrimaryDark">@color/primary_dark&lt;/item>
+ &lt;!-- theme UI controls like checkboxes and text fields -->
+ &lt;item name="android:colorAccent">@color/accent&lt;/item>
+ &lt;/style>
+&lt;/resources>
+</pre>
+
+<div style="float:right;margin-left:25px;margin-top:20px;margin-bottom:10px" id="fig3">
+<img src="{@docRoot}training/material/images/ThemeColors.png" width="250" height="445" />
+<p class="img-caption" style="margin-bottom:0px">
+<strong>그림 3.</strong> 머티리얼 테마 사용자자정</p>
+</div>
+
+
+<h2 id="StatusBar">상태 표시줄 사용자지정</h2>
+
+<p>머티리얼 테마를 사용하면 손쉽게 상태 표시줄을 사용자지정할 수 있습니다. 따라서 브랜드에 맞는 색상을 지정하고 흰색 상태 아이콘이 보이도록 충분한 대비를 제공할 수 있습니다.
+ 상태 표시줄의 사용자지정 색상을 설정하려면 머티리얼 테마를 확장할 때 <code>android:statusBarColor</code> 특성을 사용합니다.
+
+ 기본적으로 <code>android:statusBarColor</code>는 <code>android:colorPrimaryDark</code>의 값을 상속합니다.
+</p>
+
+<p>직접 상태 표시줄 뒤에 그릴 수도 있습니다. 예를 들어 사진 위에 상태 표시줄이 투명하게 표시되도록 하려면, 희미하게 어두운 그라데이션으로 흰색 상태 아이콘이 보이게 합니다.
+
+ 그렇게 하려면 <code>android:statusBarColor</code> 특성을
+<code>&#64;android:color/transparent</code>로 설정하고 필요한 경우 창 플래그를 조정합니다. 또한 {@link android.view.Window#setStatusBarColor Window.setStatusBarColor()} 메서드를 사용하여 애니메이션 또는 페이드 효과를 줄 수도 있습니다.
+
+</p>
+
+<p class="note">
+<strong>참고:</strong> 상태 표시줄은 거의 언제나 기본 도구모음과 경계가 분명히 식별되어야 합니다. 단, 이러한 표시줄 뒤에 다채로운 가장자리 이미지 또는 미디어 콘텐츠를 표시하는 경우나 아이콘이 계속 보이도록 그라데이션을 사용하는 경우는 제외됩니다.
+
+
+</p>
+
+<p>탐색 표시줄과 상태 표시줄을 사용자지정하는 경우, 둘 다 투명하게 만들거나 상태 표시줄만 수정합니다.
+ 그 밖의 경우 탐색 표시줄은 항상 검은색을 유지해야 합니다.</p>
+
+
+<h2 id="Inheritance">개별 뷰의 테마 지정</h3>
+
+<p>XML 레이아웃 정의에 있는 요소는 테마 리소스를 참조하는 <code>android:theme</code> 특성을 지정할 수 있습니다.
+ 이 특성은 요소와 모든 하위 요소의 테마를 수정하며, 인터페이스의 특정 부분에서 테마 색상표를 바꿀 때 유용합니다.
+
+</p>